4

我有两个类:父类 A 和一些子类 B,它扩展了 A 并且比 A 多了几个字段。我希望能够克隆这两个类,所以我已经覆盖了类中的clone()方法Object

由于 B 类基本上是具有一些额外字段的 A 类,因此我想在clone()B 类的实现中使用 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;
      }
    }

这样我就不必clone()在 B 的clone()方法中复制 A 方法中的所有克隆逻辑。不幸的是,这不起作用,因为Java不允许将A类的对象强制转换为B类的对象。我四处寻找有关如何执行此操作的答案,但似乎没有办法重用克隆逻辑A.这是否意味着每次在A中添加另一个字段时,我都必须手动将这个字段的复制添加到所有clone()子类的方法中。这似乎很容易出错......

4

2 回答 2

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部分是做伎俩的部分。另请参阅可克隆

于 2012-08-31T10:22:50.727 回答
2

问题是您的A#clone(). 您永远不应该clone通过 using 创建您将在方法中返回的实例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;
  }
}
于 2012-08-31T10:20:56.247 回答