web-dev-qa-db-ja.com

基本クラスメソッドから基本クラスのオーバーライドされた関数を呼び出す

public class A {
    public void f1(String str) {
        System.out.println("A.f1(String)");
        this.f1(1, str);
    }

    public void f1(int i, String str) {
        System.out.println("A.f1(int, String)");
    }
}



public class B extends A {
    @Override
    public void f1(String str) {
        System.out.println("B.f1(String)");
        super.f1(str);
    }

    @Override
    public void f1(int i, String str) {
        System.out.println("B.f1(int, String)");
        super.f1(i, str);
    }
}


public class Main {
    public static void main(String[] args) {
        B b = new B();
        b.f1("Hello");
    }
}

私はこのコードが出力することを求めています:

B.f1(String)
A.f1(String)
A.f1(int, String)

それでも私は得ています:

B.f1(String)
A.f1(String)
B.f1(int, String)
A.f1(int, String)

Bのコンテキストでは、A.f1(String)の「this」がBのインスタンスであることを理解しています。チェーンnew B1()。f1(String)->(A's)f1(String)->(A's)f1(int、String)を実行するオプションはありますか?

これは理論的な質問です。実際には、f1(String)とf1(int、String)の両方が呼び出すプライベート関数を実装するためのソリューションは明らかにAにあります。

ありがとうございました、
マキシム。

36
Maxim Veksler

残念ながら、no

私はあなたが知っていると確信していますが、完全を期すために明示的に述べます-メソッドの呼び出しを制御する2つのキーワードのみがあります:

  • this-this.method()-呼び出し元インスタンスのクラスから開始するメソッドを探します(インスタンスの「トップ」仮想テーブル-暗黙のデフォルト)
  • super-super.method()-呼び出しメソッドが定義されているクラス(呼び出しクラス)の親クラスから始まるメソッドを探す'親の仮想テーブル- 厳密には真ではない 、しかし、このように考えるのは簡単です-ありがとう@maaartinus)

別のキーワード(たとえば、現在の?)があなたが説明することをすることを想像できます:

  • current-current.method()-呼び出しメソッドが定義されているクラスから始まるメソッドを探す

しかしJavaにはそのようなキーワードはありません(まだ?)。

33
Bert F

私は恐れています、それは不可能ですが、簡単な回避策があります:

public class A {
    public void f1(String str) {
        System.out.println("A.f1(String)");
        privateF1(1, str);
    }

    private void privateF1(int i, String str) {
        System.out.println("A.f1(int, String)");
    }

    public void f1(int i, String str) {
        privateF1(i, str);
    }
}
19
maaartinus

Javaのオーバーライドされたメソッドは動的にバインドされます。つまり、オブジェクトの実際のインスタンスのタイプによって、呼び出されるものが決まります。finalメソッド(オーバーライドできません)およびprivateメソッド(継承できない)は静的にバインドされます。

C++では、対照的に、同じ動作を得るには、関数virtualを明示的に作成する必要があります。

6
Brian Agnew