Domanda

Sto riscontrando un piccolo problema in Java. Ho un'interfaccia chiamata modificabile. Gli oggetti che implementano questa interfaccia sono modificabili.

Ho anche una classe ModifyCommand (con il modello Command) che riceve due oggetti modificabili (per scambiarli in un elenco più avanti - non è una mia domanda, ho già progettato quella soluzione).

La classe ModifyCommand inizia creando cloni degli oggetti modificabili. Logicamente, ho reso la mia interfaccia modificabile estesa Cloneable. L'interfaccia definisce quindi un metodo clone () che le sue classi di implementazione devono ridefinire.

Quindi, in ModifyCommand, posso fare: firstModifiableObject.clone (). La mia logica è che le classi che implementano Modificabile dovranno ridefinire il metodo clone da Object, in quanto saranno Clonabili (questo è quello che voglio fare).

Il fatto è che quando definisco le classi implementa Modifiable e voglio sovrascrivere clone (), non me lo permette, affermando che il metodo clone () della classe Object nasconde quello di Modifiable.

Cosa devo fare? Ho l'impressione che " sto sbagliando " ...

Grazie,

Guillaume.

Modifica: pensa che dimenticherò la cosa clone (). A) supporrò che l'oggetto passato all'oggetto modificabile (implementando l'interfaccia) sia già clonato o b) creerò un altro metodo chiamato, ad esempio, copy (), che sostanzialmente farebbe una copia profonda dell'oggetto modificabile ( o forse la soluzione generica funzionerà ...).

È stato utile?

Soluzione

Se stai usando Java 1.5 o versioni successive, puoi ottenere il comportamento che desideri e rimuovere il casting in questo modo:

public interface Modifiable<T extends Modifiable<T>> extends Cloneable {
    T clone();
}

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

Poiché Foo estende Object, ciò soddisfa ancora il contratto originale della classe Object. Il codice che non perfeziona correttamente il metodo clone () non verrà compilato, a causa dei vincoli aggiuntivi imposti dall'interfaccia modificabile. Come bonus, il codice chiamante non deve trasmettere il risultato del metodo clone.

Altri suggerimenti

Non è necessario ridefinire il metodo clone sull'interfaccia Modificabile.

Controlla la documentazione: http: / /java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html

Comprendo che stai cercando di forzare tutti a sovrascrivere il metodo clone (), ma non puoi farlo.

In un altro modo, non è possibile sovrascrivere una classe su un'interfaccia:

Il metodo clone () è sempre associato al Object.class e non all'interfaccia clonabile. Puoi semplicemente sovrascriverlo su un altro oggetto, non in un'interfaccia.

Aggiungendo alla risposta di Sean Reilly, questo dovrebbe risolvere il tuo problema ed è più sicuro per i tipi. Si compila e funziona bene con me su JDK6:

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

Non ho potuto testarlo con Java 5 perché non l'ho installato, ma credo che funzionerebbe bene.

Hai definito la firma esattamente com'è nell'oggetto?

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

Questo dovrebbe essere compilato - aggiungi un codice personalizzato al corpo. Wikipedia è stato sorprendentemente utile su questo.

Che aspetto ha la firma del metodo per il metodo clone? Affinché corrisponda all'interfaccia Clonable dovrebbe restituire un oggetto. Se lo stai dichiarando come reso modificabile, questo potrebbe essere il problema.

classe pubblica 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();

}

}

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top