4

親クラス A と、A を拡張し、A よりもいくつかのフィールドを持つサブクラス B の 2 つのクラスがあります。これらのクラスの両方を複製できるようにしたいのでclone()、クラスからメソッドをオーバーライドしましたObject

クラスBは基本的にいくつかの追加フィールドを持つクラスAであるため、クラスBの実装でクラスAのクローンを使用したいと思いますclone()。次の行に沿って何かを試しました:

    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()この方法では、A のメソッドから B のメソッドのすべての複製ロジックを複製する必要はありませんclone()。残念ながら、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を使用してメソッドで返すインスタンスを作成しないでください。現在発生しているエラーを正確に回避するために、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 に答える