我在Java中遇到一个小问题。我有一个名为Modifiable的界面。实现此接口的对象是可修改的。

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

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

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

问题是,当我定义类实现Modifiable并且我想覆盖clone()时,它不会让我说明Object类中的clone()方法隐藏了一个来自Modifiable的方法。

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

谢谢,

纪尧姆。

编辑:它认为我会忘记clone()的事情。我将a)假设传递给Modifiable对象(实现接口)的对象已经克隆或b)创建另一个调用的方法,例如copy(),它基本上会执行Modifiable对象的深层复制(或者通用解决方案可以工作......)。

有帮助吗?

解决方案

如果你使用的是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
    }
}

由于Foo扩展了Object,这仍然满足Object类的原始契约。由于Modifiable接口施加了额外的限制,因此无法正确优化clone()方法的代码将无法编译。作为奖励,调用代码不必转换克隆方法的结果。

其他提示

您无需在界面Modifiable上重新定义克隆方法。

查看文档: http:/ /java.sun.com/j2se/1.4.2/docs/api/java/lang/Cloneable.html

我知道你试图强迫所有人重写克隆方法(),但是你不能这样做。

另一方面,您无法覆盖接口上的类:

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

除了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();
    }
}

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

您是否完全按照对象定义签名?

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

这应该编译 - 向主体添加自定义代码。 维基百科对此非常有帮助。

克隆方法的方法签名是什么样的?为了匹配Clonable接口,它必须返回一个Object。如果你宣称它是返回一个可修改的那么那可能是问题。

公共类CloningExample实现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();

}

}

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top