Interfaz clonable obligatoria en Java

Estoy teniendo un pequeño problema en Java. Tengo una interfaz llamada Modificable. Los objetos que implementan esta interfaz son modificables.

También tengo una clase ModifyCommand (con el patrón de Comando) que recibe dos objetos modificables (para intercambiarlos en una lista más adelante, esa no es mi pregunta, ya diseñé esa solución).

La clase ModifyCommand comienza haciendo clones de los objetos modificables. Lógicamente, hice que mi interfaz modificable se extendiera a Cloneable. La interfaz entonces define un método clone () que sus clases de implementación deben redefinir.

Luego, en ModifyCommand, puedo hacer: firstModifiableObject.clone (). Mi lógica es que las clases que implementan Modifiable deberán redefinir el método de clonación de Object, ya que serán Clonables (eso es lo que quiero hacer).

La cosa es que cuando defino las clases implementa Modifiable y quiero anular clone (), no me lo permite, indicando que el método clone () de la clase Object oculta el de Modifiable.

¿Que debería hacer? Tengo la impresión de que “lo estoy haciendo mal” …

Gracias,

Guillaume.

Edit: creo que olvidaré el clon (). Supongo que a) el objeto pasado al objeto modificable (implementando la interfaz) ya está clonado o b) creará otro método llamado, por ejemplo, copy (), que básicamente haría una copia profunda del objeto modificable ( o tal vez la solución genérica funcionará …).

Si está utilizando java 1.5 o superior, puede obtener el comportamiento que desea y eliminar el lanzamiento de esta manera:

public interface Modifiable> extends Cloneable { T clone(); } public class Foo implements Modifiable { public Foo clone() { //this is required return null; //todo: real work } } 

Dado que Foo extiende Object, esto aún satisface el contrato original de la clase Object. El código que no refina el método clone () correctamente no se comstackrá, debido a las restricciones adicionales impuestas por la interfaz modificable. Como beneficio adicional, el código de llamada no tiene que emitir el resultado del método de clonación.

No es necesario redefinir el método de clonación en la interfaz Modificable.

Consulte la documentación: http://java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html

Entiendo que está intentando forzar a todos a anular el método de clonación (), pero no puede hacerlo.

De otra manera, no puede anular una clase en una interfaz:

El método clone () siempre está asociado con Object.class y no con la interfaz clonable. Solo puede anularlo en otro objeto, no en una interfaz.

Agregando a la respuesta de Sean Reilly, esto debería resolver su problema, y ​​es más seguro. Se comstack y funciona bien conmigo en JDK6:

 public interface Modifiable> extends Cloneable { T clone(); } public class Test implements Modifiable { @Override public Test clone() { System.out.println("clone"); return null; } public static void main(String[] args) { Test t = new Test().clone(); } } 

No pude probarlo con Java 5 porque no lo tengo instalado, pero creo que funcionaría bien.

¿Definiste la firma exactamente como está en el objeto?

 public Object clone() throws CloneNotSupportedException { return super.clone(); } 

Esto debería comstackr – agregar código personalizado al cuerpo. Wikipedia fue sorprendentemente útil en este caso.

¿Cómo se ve tu firma de método para tu método de clonación? Para que coincida con la interfaz Clonable tendría que devolver un Objeto. Si lo está declarando como que devuelve un Modificable, entonces ese podría ser el problema.

La clase pública CloningExample implementa Cloneable {

 private LinkedList names = new LinkedList(); public CloningExample() { names.add("Alex"); names.add("Melody"); names.add("Jeff"); } public String toString() { StringBuffer sb = new StringBuffer(); Iterator i = names.iterator(); while (i.hasNext()) { sb.append("\n\t" + i.next()); } return sb.toString(); } public Object clone() { try { return super.clone(); } catch (CloneNotSupportedException e) { throw new Error("This should not occur since we implement Cloneable"); } } public Object deepClone() { try { CloningExample copy = (CloningExample)super.clone(); copy.names = (LinkedList)names.clone(); return copy; } catch (CloneNotSupportedException e) { throw new Error("This should not occur since we implement Cloneable"); } } public boolean equals(Object obj) { /* is obj reference this object being compared */ if (obj == this) { return true; } /* is obj reference null */ if (obj == null) { return false; } /* Make sure references are of same type */ if (!(this.getClass() == obj.getClass())) { return false; } else { CloningExample tmp = (CloningExample)obj; if (this.names == tmp.names) { return true; } else { return false; } } } public static void main(String[] args) { CloningExample ce1 = new CloningExample(); System.out.println("\nCloningExample[1]\n" + "-----------------" + ce1); CloningExample ce2 = (CloningExample)ce1.clone(); System.out.println("\nCloningExample[2]\n" + "-----------------" + ce2); System.out.println("\nCompare Shallow Copy\n" + "--------------------\n" + " ce1 == ce2 : " + (ce1 == ce2) + "\n" + " ce1.equals(ce2) : " + ce1.equals(ce2)); CloningExample ce3 = (CloningExample)ce1.deepClone(); System.out.println("\nCompare Deep Copy\n" + "--------------------\n" + " ce1 == ce3 : " + (ce1 == ce3) + "\n" + " ce1.equals(ce3) : " + ce1.equals(ce3)); System.out.println(); } 

}