0

次のコードを見てみましょう。

public class Test {

    class A {
        public A() {}

        private void testMethod() {
            System.out.println("A");
        }
    }

    class B extends A {
        public B() { super(); }

        private void testMethod() {
            System.out.println("B");
        }
    }

    public Test() { }

    public A get() {
        return new B();
    }

    public static void main(String[] args) {
        new Test().get().testMethod();
    }
}

そのコードがB. A代わりに書かれています。

クラスが含まれる内部クラスのプライベート メソッドを呼び出すことができるという事実は (少なくとも私には) 奇妙に感じるかもしれませんが (なぜそのようにしたのですか?)、しかし私が本当に理解できないのは、ポリモーフィズムがなぜそうしないのかということです。動作しません。

つまり、 fromTest.main()を呼び出すことができれば、 A.testMethod()call も呼び出すことは明らかB.testMethod()です。Java はオブジェクトの動的型を判別することもできますが、なぜ Java は動的型のメソッドではなく、宣言された型のメソッドを呼び出すのでしょうか? この動作は次の方法で確認できます。

public static void main(String[] args) {
    B b = new Test().new B();
    A a = b;
    b.testMethod(); // writes B
    a.testMethod(); // writes A
}

また、なぜこれが の場合にのみ発生するのTest.A.testMethod()ですprivateか?

4

3 に答える 3

5

あなたが期待している動作は、仮想メソッドから来ています。
プライベート メソッドは決して仮想ではありません。

代わりに、たまたま同じ名前を持つ 2 つの無関係なメソッドがあります。

于 2012-09-14T14:14:10.350 に答える
3

JLS #15.2.3で定義されています。

コンパイル時の宣言に private 修飾子がある場合、呼び出しモードは非仮想です。

JLS #15.4.4

呼び出しモードが非仮想の場合、オーバーライドは許可されません。クラス T のメソッド m が呼び出されます。

実行時のオブジェクトの実際の型(あなたの場合)とは対照的にT、宣言された型はどこにありますか?つまり、プライベート メソッドにはポリモーフィズムがありません。AB

于 2012-09-14T14:23:07.373 に答える
0

Java では、すべての非静的メソッドはデフォルトで「仮想関数」です。特定の 2 種類の非静的メソッドは非仮想です。オーバーライドできないキーワード final でマークされたメソッドと、継承されないプライベート メソッドです。

http://en.wikipedia.org/wiki/Virtual_function#Java

于 2012-09-14T14:14:06.323 に答える