10

次のクラスを検討してください

class A{
    public void init(){
        //do this first;
    }
    public void atEnd(){
        //do this after init of base class ends
    }
}

class B1 extends A{

    @Override
    public void init()
    {
        super.init();
        //do new stuff.
        //I do not want to call atEnd() method here...
    }
}

すでに開発されているB1、B2、...Bnの子クラスがいくつかあります。それらはすべてクラスAを拡張します。それらすべてに新しい機能を追加したい場合は、クラスA内のメソッドでそれを定義するのが最適です。ただし、メソッドは常に直前に自動的に呼び出される必要があります。子クラスのinit()メソッドは終了します。これを行う基本的な方法の1つは、子クラスのinit()メソッドの最後にatEnd()メソッド呼び出しを再度追加することです。しかし、これを賢く行う他の方法はありますか?

4

4 に答える 4

21

これを行う1つの方法は、init()finalを作成し、その操作を2番目のオーバーライド可能なメソッドに委任することです。

abstract class A {
  public final void init() {
    // insert prologue here
    initImpl();
    // insert epilogue here
  }
  protected abstract void initImpl();
}

class B extends A {
  protected void initImpl() {
    // ...
  }
}

誰かが呼び出すたびinit()に、プロローグとエピローグが自動的に実行され、派生クラスは何もする必要がありません。

于 2012-05-17T11:58:19.033 に答える
4

別の考えは、アスペクトを織り込むことです。ポイントカットにアドバイスの前後を追加します。

于 2012-05-17T11:59:45.657 に答える
3

を作成し、途中でinit() finalその呼び出しをオーバーライドするための別のメソッドを提供します。init()

class A{
    public final void init(){
        //do this first;
    }

    protected void initCore() { }

    public void atEnd(){
        //do this after init of base class ends
    }
}

class B1 extends A{

    @Override
    protected void initCore()
    {
        //do new stuff.
    }
}
于 2012-05-17T11:57:10.210 に答える
0

他の答えは合理的な回避策ですが、正確な質問に対処するために:いいえ、これを自動的に行う方法はありません。明示的に呼び出す必要がありますsuper.method()

于 2019-03-13T15:06:14.303 に答える