Pergunta

Estou tendo um pequeno problema em Java. Eu tenho uma interface chamada modificáveis. Objetos implementar essa interface são modificáveis.

Eu também tenho uma classe ModifyCommand (com o padrão de comando) que recebem dois objetos modificáveis. (Para trocá-los em uma lista mais adiante - que não é a minha pergunta, eu projetei essa solução já)

A classe ModifyCommand começa por fazer clones dos objetos modificáveis. Logicamente, eu fiz a minha interface modificável estende Cloneable. A interface, em seguida, define um método clone () que suas classes de execução devem redefinir.

Então, em ModifyCommand, eu posso fazer: firstModifiableObject.clone (). Minha lógica é que as classes que implementam Modifiable terá que redefinir o método clone do objeto, como eles serão Cloneable (que é o que eu quero fazer).

A coisa é, quando eu definir classes implementos modificáveis ??e eu quero substituir clone (), ele não vai me deixar, afirmando que o método clone () das peles classe de objeto a de modificáveis.

O que devo fazer? Tenho a impressão de que "eu estou fazendo errado" ...

Obrigado,

Guillaume.

Edit: ele acha que eu vou esquecer a coisa clone (). Vou quer a) assumir que o objeto passado para o objeto modificável (implementação da interface) já é clonado ou b) fazer um outro método chamado, por exemplo, copiar (), que, basicamente, fazer uma deep-cópia do objeto modificável ( ou talvez a solução genérico vai funcionar ...).

Foi útil?

Solução

Se você estiver usando java 1.5 ou superior, você pode obter o comportamento desejado e remover lançando desta forma:

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
    }
}

Desde Foo estende Object, isto satisfaz ainda o contrato original da classe Object. Código que não refinar o método clone () corretamente não irá compilar, por causa das restrições adicionais impostas pela interface modificável. Como um bônus, chamar código não tem que converter o resultado do método clone.

Outras dicas

Você não precisa redefinir o método clone na interface modificável.

Verifique a documentação: http: / /java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html

Eu entendo que você está tentando forçar todos a método clone override (), mas você não pode fazê-lo.

De outra forma, você não pode substituir uma classe em uma interface:

O método clone () está sempre associada a Whit Object.class e não a interface clonável. Você só pode substituí-lo em um outro objeto, não em uma interface.

Somando-se a resposta de Sean Reilly, este deve resolver o seu problema, e é mais tipo seguro. Ele compila e executa bem comigo em 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();
    }
}

Eu não poderia testá-lo com Java 5, porque eu não tê-lo instalado, mas eu acho que iria funcionar bem.

Você definir a assinatura exatamente como no objeto?

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

Isso deve compilar - código personalizado add para o corpo. Wikipedia foi surpreendentemente útil em um presente.

O que a sua assinatura do método para o seu olhar de método de clone como? Para que ele coincidir com a interface clonable ele teria que retornar um objeto. Se você está declarando-lo como retornando um Modifiable seguida, que poderia ser o problema.

classe pública CloningExample implementos 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();

}

}

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top