我在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对象的深层复制(或者通用解决方案可以工作......)。
答案 0 :(得分:10)
如果你使用的是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()方法的代码将无法编译。作为奖励,调用代码不必转换克隆方法的结果。
答案 1 :(得分:1)
您无需在界面Modifiable上重新定义克隆方法。
查看文档:{{3}}
我知道你试图强迫所有人重写克隆方法(),但是你不能这样做。
另一方面,您无法覆盖接口上的类:
clone()方法始终与Object.class相关联,而不是可克隆接口。您只需在另一个对象上覆盖它,而不是在界面中覆盖它。
答案 2 :(得分:1)
除了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测试它,因为我没有安装它,但我想它会正常工作。
答案 3 :(得分:0)
您是否完全按照对象定义签名?
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
这应该编译 - 向主体添加自定义代码。 Wikipedia对此问题非常有帮助。
答案 4 :(得分:0)
克隆方法的方法签名是什么样的?为了匹配Clonable接口,它必须返回一个Object。如果你宣称它是返回一个可修改的那么那可能是问题。
答案 5 :(得分:0)
公共类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();
}
}