1

抽象スーパークラスといくつかの派生クラスがあります。
メソッドを作成したい

createNew()   

派生クラスで呼び出されると、すべてのメンバーのスマートコピーを使用して派生クラスの新しいインスタンスが作成されます。
作成に重要なすべてのメンバーは抽象クラスに含まれているため、コードは同じである必要があります。
スーパークラスでcreateNew()の実装を書くことはできますか?

そんな感じ

SonA sonA2 = sonA1.createNew()   
SonB sonB2 = sonB1.createNew()  

コードが同一であるため、absスーパークラスが実装を行う必要があります。
ありがとう。

4

4 に答える 4

3

実装は、抽象クラスと具象クラスに分割する必要があります。Template Method パターンを使用してそれを行うことができます。

public abstract class AbstractSon {
    protected abstract AbstractSon createNewImpl();
    public AbstractSon createNew() {
        AbstractSon res = createNewImpl();
        res.name = "default name";
        return res;
    }
}
public class Son1 extends AbstractSon {
    protected AbstractSon createNewImpl() {
        return new Son1();
    }
}
public class Son2 extends AbstractSon {
    protected AbstractSon createNewImpl() {
        return new Son2();
    }
}

責任を別の方法で分割して、正確な戻り値の型を取得できます。

public abstract class AbstractSon {
    protected void prepare(AbstractSon toPrepare) {
        toPrepare.name = "default name";
    }
}
public class Son1 extends AbstractSon {
    public Son1 createNew() {
        Son1 res = new Son1();
        prepare(res);
        return res;
    }
}
public class Son2 extends AbstractSon {
    public Son2 createNew() {
        Son2 res = new Son2();
        prepare(res);
        return res;
    }
}
于 2012-05-09T14:03:31.517 に答える
1

1つの可能性は、コピーを別のメソッドに分解し、それを派生クラスから呼び出すことですcreateNew()

abstract class Base {

  public abstract Base createNew();

  protected void populate(Base out) {
    // copy the data from `this' to `out'
  }
}

class Derived1 extends Base {
  public Derived1 createNew() {
    Derived1 ret = new new Derived1();
    populate(ret);
    return ret;
  }
}

class Derived1 extends Base {
  public Derived2 createNew() {
    Derived2 ret = new new Derived2();
    populate(ret);
    return ret;
  }
}
于 2012-05-09T14:06:37.103 に答える
1

メソッドで使用されるコールバックとして機能する抽象メソッドを作成し、そのメソッドを各サブクラスにcreateNew実装します。共通スーパークラスの具体的な偶数メソッドにすることができます。上記の抽象メソッドは、それぞれのサブクラスの新しいインスタンスを返します。createNewfinal

別のアプローチは、どのクラスが呼び出されたかを反映して見つけ、それcreateNewに基づいて新しいインスタンスを作成することです。

于 2012-05-09T14:01:53.653 に答える
1

このコードを記述できます (リフレクションを使用しgetClass().newInstance()て、メソッドが定義されているクラスではなく実際のクラスのインスタンスを取得します) が、いくつかの問題があります。たとえば、このメソッドから何を返すつもりですか?

スーパータイプを返す必要があります。つまり、呼び出しごとにキャストする必要があります。

通常の解決策はcopy()、すべてのレベルで定義するメソッドを定義することです。次に、これを行うことができます:

 class SonA {
     SonA createNew() {
         SonA result = new SonA();
         this.copy( result );
         return result;
     }

     void copy( SonA target ) {
         super.copy( target );

         // copy my fields to target ...
     }
 }

また、コピー コンストラクターについても読みたいと思うかもしれません。

于 2012-05-09T14:03:52.033 に答える