0

Aのコンストラクターから呼び出すメソッド「say」を持つ基本クラスAがあります。すべての継承可能なクラスは、メソッド「say」をそのまま使用します。ただし、クラスの 1 つでこのメソッドを再定義する必要があります。それはどのように可能ですか?

確かに、基本メソッド「say」を抽象として示すことはできますが、その場合、継承可能なすべてのクラスで同じメソッド「say」をコピーする必要があります。

ベース1を抽象として示さずにメソッドを再定義するだけでは、呼び出されません。

public abstract class A(){
     public A(){
        say();  //  <- wanna call this method from heritable class, if its redefined. 
     }
     protected void say(){};
}

public class B extends A(){
     public B(){
        super();
     }
     private void say(){};
}

リファクタリング 1

public abstract class A(){
     public A(){
       //  constructor methods             
     }
     protected void say(){};
     protected void executeSay(){
       say();
     }
}

public class B extends A(){
     public B(){
        super();
        executeSay();
     }
     @Override
     protected void say(){};
}
4

4 に答える 4

11

コンストラクターからオーバーライド可能なメソッドを呼び出すことは、よく知られたアンチパターンです。サブクラスのコンストラクターが完了する前にサブクラスのメソッドが呼び出され、初期化されていないオブジェクトが観察されるため、ほぼ確実にコードが壊れます。したがって、このアンチパターンの実現に関連する Java の技術に関する詳細なアドバイスは差し控えたほうがよいでしょう。

要件を満たすための唯一の安全な方法は、構築を終了させて​​から、initialize種類のメソッドを呼び出すことです。が常に呼び出されるようにする場合initializeは、コンストラクターを非パブリックにして、代わりにファクトリ メソッドを提供します。

残念ながら、Java を正しく機能させるには、かなりの作業が必要です。

于 2013-05-15T07:05:29.253 に答える
4

抽象クラスをインスタンス化することはできません。つまり、抽象クラス参照を具体的な継承クラスにリンクする必要があります。例えば。A a = 新しい B(); その場合、B が say() メソッドを再定義した場合、B の say メソッドが呼び出されます。

public class TestPad {
    public static void main(String[] args) {
        A a = new B();
    }
}
abstract class A {
    public A() {
    say();
    }
    public void say(){
    System.out.println("A");
    };
}

class B extends A {
    public B() {
    super();
    }
    public void say() {
    System.out.println("B");
    }
}

出力はBになります

于 2013-05-15T07:16:28.023 に答える
3
public class B extends A {
    public B() {
        super();
    }

    @Override
    protected void say() {
        // your diffent say code
    };
}

可視性を非公開にすることが許可されているかどうかはわかりません。

于 2013-05-15T07:04:41.210 に答える
0

ポリモーフィックなメソッド呼び出しのため、あなたの場合、オーバーライドすると B.say() が呼び出されます。

say()しかし、@sanbhat がコメントしたように、の可視性をに変更する必要がありますprotected

于 2013-05-15T07:05:04.523 に答える