Java 在子类中实现clone()

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

我有两个类:父类A和一些子类B,它们扩展了A,并且比A多了几个字段。我希望能够克隆这两个类,因此我从
对象
类重写了
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()
来构造新对象,您的类应该这样做,但是如果它们中的任何一个通过调用副本构造函数来构造新对象,您的类也必须这样做。我觉得一个人应该使用复制构造函数这一概念很令人讨厌,因为克隆从根本上说是坏的,因为它“坏”的全部原因首先是相信复制构造函数在某种程度上更好。