我有两个类:父类A和一些子类B,它扩展了A并且还有几个字段而不是A.我希望能够克隆这两个类,所以我覆盖了clone()
来自Object
类的方法。
由于B类基本上是带有一些额外字段的A类,我想在B类的clone()
实现中使用A类的克隆。我尝试了以下几点:
public class A
{
public Object clone()
{
A cloneA = new A();
cloneA.foo = this.foo;
cloneA.bar = this.bar;
return cloneA;
}
}
public class B extends B
{
public Object clone()
{
Object cloneA = super.clone();
B cloneB = (B)cloneA;
cloneB.fieldSpecificForB = this.fieldSpecificForB;
return cloneB;
}
}
这样我就不必在B的clone()
方法中复制A的clone()
方法中的所有克隆逻辑。不幸的是,这不起作用,因为Java不允许将类A的对象转换为类B的对象。我搜索了如何执行此操作的答案,但似乎没有办法重用克隆逻辑答:这是否意味着每次我向A添加另一个字段时,我必须手动将此字段的复制添加到所有子类的clone()
方法中。这似乎非常容易出错......
答案 0 :(得分:7)
clone
的工作方式是,它会自动为您复制所有字段。但是,您必须致电super.clone()
才能使其正常工作:
public class A implements Cloneable // add 'implements'
{
public Object clone()
{
A cloneA = super.clone(); // this copies all fields and returns something of *the same type* as 'this'...
return cloneA;
}
}
public class B extends A //supposed to extend 'A' right?
{
public Object clone()
{
Object cloneA = super.clone(); // this returns object of runtime type B
B cloneB = (B)cloneA; // will work
return cloneB;
}
}
编辑:实际上你的clone
方法现在什么都不做,所以它等同于写:
public class A implements Cloneable //add 'implements'
{
}
public class B extends A //supposed to extend 'A' right?
{
}
implements Cloneable
部分就是诀窍。另请参阅Cloneable。
答案 1 :(得分:2)
问题是您A#clone()
的实施。您永远不应该使用clone
创建将在new
方法中返回的实例,而应始终通过调用super.clone()
来创建,以避免您现在遇到的错误。
因此请将A类调整为
public class A
{
@Override
protected Object clone() throws CloneNotSupportedException
{
A cloneA = (A)super.clone();
cloneA.foo = this.foo;
cloneA.bar = this.bar;
return cloneA;
}
}