1

コード:

class TestA {
    public void foo(String... strings ) {
        System.out.println("TestA::foo");
    }

    public void bar(String a){
        System.out.println("TestA::bar");
    }
}

class TestB extends TestA {
    public void foo(String strings ) {
        System.out.println("TestB::foo");
    }

    public void bar(String a){
        System.out.println("TestB::bar");
    }

    public static void main(String[] args) {
        TestA a = new TestB();
        a.foo("foo");
        a.bar("bar");
    }
}

出力は

TestA::foo
TestB::bar

したがってB::bar、オーバーライドされB::fooてオーバーロードされ、関数がオーバーロードされると、参照先のオブジェクトのタイプではなく、参照のデータ型が重要になります。私は正しいですか?

4

3 に答える 3

1

関数がオーバーロードされている場合、それが指しているオブジェクトのタイプではなく、参照のデータ型が重要です。私は正しいですか?

はい。

オーバーロードはコンパイル時のバインディングであり、その時点で認識されているのは参照のタイプのみです。オーバーライドは実行時のバインディングであり、オブジェクトのタイプに基づいて呼び出しが実行されます。

于 2013-01-08T06:03:50.133 に答える
1

あなたの分析が正確に何であるかはわかりませんが、これが私が見るものです:

  • TestA.bar(String)によってオーバーライドされますTestB.bar(String)
  • TestA.foo(String...)によって継承されTestB、でオーバーロードさTestBれますTestB.foo(String)

ただし、コンパイラはそれがオブジェクトa.foo("foo")に対して呼び出されていることを認識しTestBていないため、オーバーロードについては認識していません。したがって、それをシグニチャを持つメソッドの呼び出しにコンパイルしますfoo(String...)aそれがであることがわかっている場合TestB、それはより厳密に一致するためにバインドされfoo(String)ます(配列引数への変換は必要ありません)。

于 2013-01-08T06:09:38.437 に答える
1

TestBクラスはTestAを継承し、オーバーライドされたbarメソッドとオーバーロードされたfooメソッドを持ちます。TestAのコンパイル時にaはTestBの参照を持っているため、オーバーロードされたメソッドは実行されませんが、オーバーライドされたbarメソッドの場合はオーバーライドされたメソッドの呼び出しです。実行時に行われます。オーバーロードされたメソッドはコンパイル時にロードされ、実行時にオーバーライドされたメソッドであるためです。

于 2013-01-08T06:11:01.800 に答える