Java 在子类中实现clone()
我有两个类:父类A和一些子类B,它们扩展了A,并且比A多了几个字段。我希望能够克隆这两个类,因此我从Java 在子类中实现clone(),java,inheritance,clone,Java,Inheritance,Clone,我有两个类:父类A和一些子类B,它们扩展了A,并且比A多了几个字段。我希望能够克隆这两个类,因此我从对象类重写了clone()方法 由于类B基本上是带有一些额外字段的类A,我想在类B的clone()实现中使用类A的克隆。我尝试了以下方法: public class A { public Object clone() { A cloneA = new A(); cloneA.foo = this.foo; cl
对象
类重写了clone()
方法
由于类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的克隆逻辑。这是否意味着每次我向A添加另一个字段时,我必须手动将此字段的复制添加到所有子类的clone()
方法中。这似乎非常容易出错…问题在于您的A#clone()
实现。决不应使用new
创建将在clone
方法中返回的实例,而应始终调用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;
}
}
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;
}
}
编辑:实际上你的克隆
方法现在什么都不做,所以它相当于写:
public class A implements Cloneable //add 'implements'
{
}
public class B extends A //supposed to extend 'A' right?
{
}
实现可克隆
部分就是实现这一技巧的部分。另请参见。Like@Mathias的可能重复说明问题在于B没有扩展A类。如果您无法扩展,那么您应该复制。我发现我在原来的帖子中遗漏了一些代码。我更改了它,以便更接近我在代码中尝试执行的操作。谢谢您的回答。我注意到我在OP中犯了一些错误(主要是B没有扩展A,A.clone()没有返回任何内容)。我似乎误解了可克隆接口和super.clone()的工作方式。这次我将使用您的示例来实现它。如果层次结构上的所有类都通过调用super.clone()
来构造新对象,您的类应该这样做,但是如果它们中的任何一个通过调用副本构造函数来构造新对象,您的类也必须这样做。我觉得一个人应该使用复制构造函数这一概念很令人讨厌,因为克隆从根本上说是坏的,因为它“坏”的全部原因首先是相信复制构造函数在某种程度上更好。