なぜこれが起こっているのか理解できないという奇妙なことに直面したとき、私はコードをテストしていました。そこで、そこで起こったことの簡単な例を挙げます。
これらのクラスを検討してください
public class A {
public void print(A a) {
System.out.println("A");
}
}
public class B extends A {
public void print() {
System.out.println("B");
}
}
public class C extends B {
public void print(A a) {
System.out.println("C");
}
}
public class E extends C {
public void print(E e) {
System.out.println("E");
}
}
今私のメインメソッドでは、この種のインスタンス化があります:
B b = new E();
C c = new E();
E e = new E();
これらのメソッドを呼び出して、次の出力を取得します。
b.print(b);
c.print(e);
出力:
C
C
2 つの説明がありますが、それぞれがこれらのメソッド呼び出しの 1 つと矛盾しています。また、私の説明はどちらも完全に間違っている可能性があるため、ここでは何も主張していません.
解説1
b.print(b)
:b
のインスタンスでE
あり、 にアップキャストされB
ます。タイプの引数を取るメソッドがありますがB
、クラスによってオーバーロードされています。ただし、このメソッドへの引数は にアップキャストされるため、メソッド呼び出しは(は のスーパークラスであるため) のシグネチャと一致し、結果は有理数になります。print
A
E
b
B
C.print(A a)
C
E
c.print(e)
: 上記と同じように考えても、ここでの出力については説明しません。c
のインスタンスでE
あり、 にアップキャストされC
ます。タイプの引数を取るメソッドがありますがC
、クラスによってオーバーロードされています。しかし、上記のケースとは対照的に、このメソッドへの引数は、の署名に一致する です。したがって、この推論により、出力は E になるはずでしたが、そうではありません!print
A
E
e
E.print(E e)
解説2
ここでは、2 番目のメソッド呼び出しとその理由から始めます。
c.print(e)
:c
のインスタンスでE
あり、 にアップキャストされC
ます。type の引数を取るメソッドがありC
ます。このメソッドの引数は、 のインスタンスであり、 のサブクラスです。アップキャストされているので非公開です。したがって、メソッド呼び出しは の署名と一致し、出力はこのロジックによって合理的です。print
A
e
E
A
E.print(E e)
c
C.print(A a)
b.print(b)
:b
のインスタンスでE
あり、 にアップキャストされB
ます。タイプの引数を取るメソッドがありますB
(これも非表示です)。したがって、メソッド呼び出しは の署名と一致し、このロジックにより、出力は A であるはずでしたが、そうではありません。print
A
A.print(A a)
ここで何が起こっているのか、本当に混乱しています。誰か説明してくれませんか。