Java中的强制可克隆接口

Java中的强制可克隆接口,java,interface,overriding,clone,Java,Interface,Overriding,Clone,我在Java中遇到了一个小问题。我有一个叫做Modifiable的接口。实现此接口的对象是可修改的 我还有一个ModifyCommand类(带有命令模式),它接收两个可修改的对象(在后面的列表中交换它们-这不是我的问题,我已经设计了这个解决方案) ModifyCommand类首先创建可修改对象的克隆。从逻辑上讲,我使我的可修改接口可克隆。然后接口定义一个clone()方法,其实现类必须重新定义该方法 然后,在ModifyCommand中,我可以执行以下操作:firstModifiableObje

我在Java中遇到了一个小问题。我有一个叫做Modifiable的接口。实现此接口的对象是可修改的

我还有一个ModifyCommand类(带有命令模式),它接收两个可修改的对象(在后面的列表中交换它们-这不是我的问题,我已经设计了这个解决方案)

ModifyCommand类首先创建可修改对象的克隆。从逻辑上讲,我使我的可修改接口可克隆。然后接口定义一个clone()方法,其实现类必须重新定义该方法

然后,在ModifyCommand中,我可以执行以下操作:firstModifiableObject.clone()。我的逻辑是,实现Modifiable的类必须从Object重新定义clone方法,因为它们是可克隆的(这就是我想要做的)

问题是,当我定义类实现Modifiable并且我想重写clone()时,它不允许我这样做,它声明对象类中的clone()方法隐藏了对Modifiable的方法

我该怎么办?我的印象是“我做错了”

谢谢

纪尧姆


编辑:我想我会忘记克隆()的事情。我要么a)假设传递给可修改对象(实现接口)的对象已经被克隆,要么b)创建另一个方法,例如copy(),该方法基本上可以对可修改对象进行深度复制(或者通用解决方案可以工作…。

您定义的签名是否与对象中的签名完全相同

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

这应该是编译-向正文中添加自定义代码。这一点非常有用。

克隆方法的方法签名是什么样的?为了匹配可克隆接口,它必须返回一个对象。如果您将其声明为返回可修改的,那么这可能就是问题所在。

您不需要在接口Modifiable上重新定义clone方法

检查文档:

我知道您试图强制所有人重写clone method(),但您不能这样做

另一方面,您不能重写接口上的类:


clone()方法始终与Object.class关联,而不是与cloneable接口关联。您只需在另一个对象上覆盖它,而不是在接口中。

如果您使用的是java 1.5或更高版本,您可以通过以下方式获得所需的行为并删除强制转换:

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
    }
}
公共接口可修改扩展可克隆{
T克隆();
}
公共类Foo实现了可修改的{
public Foo clone(){//这是必需的
返回null;//todo:实际工作
}
}

因为Foo扩展了对象,所以它仍然满足对象类的原始约定。由于可修改接口施加的附加约束,无法正确优化clone()方法的代码将无法编译。作为奖励,调用代码不必强制转换克隆方法的结果。

再加上Sean Reilly的答案,这将解决您的问题,并且更安全。它在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();
    }
}
公共接口可修改扩展可克隆{
T克隆();
}
公共类测试实现了可修改的{
@凌驾
公共测试克隆(){
System.out.println(“克隆”);
返回null;
}
公共静态void main(字符串[]args){
测试t=新测试().clone();
}
}

我无法用Java 5测试它,因为我没有安装它,但我想它可以正常工作。

公共类CloningExample实现了可克隆性{

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

}

}

你说得对。漂亮的小把戏!正如您所怀疑的,它在Java5中可以正常工作。