3
 class A{
 void m1(A a) {System.out.print("A");}
  } 
  class B extends A{
  void m1(B b) {System.out.print("B");}
  } 
  class C extends B{
  void m1(C c) {System.out.print("C");}
  }

 public class d {

 public static void main(String[] args) {

  A c1 = new C(); C c2 = new C();c1.m1(c2);

 }}

此代码的输出是'A'.

但是,如果我将 A 类修改为:

 class A{
 void m1(C a) {System.out.print("A");}
  }

那么输出是'C'. 有人可以解释一下这段代码是如何工作的吗?

4

1 回答 1

10

(通过对参数类型和实现使用相同的继承层次结构,您已经使这比需要的更加混乱。将它们分开可能有助于在您的脑海中简化它。)

的类型c1A。因此,在计算要调用哪个方法签名时,编译器只能查看在A.

所以在第一种情况下,编译器将调用m1(A); 在第二种情况下,编译器将调用m1(C).

现在在第一种情况下,该m1(A)方法永远不会被覆盖,因此实际上执行时类型c1是无关紧要的。

在第二种情况下,m1(C)被 覆盖C,因此C调用 in 中的实现,因为执行时类型c1C

所以请记住:

  • 重载解析(调用哪个方法签名)在编译时根据方法目标和参数表达式的编译时类型确定
  • 该方法签名(覆盖)的实现基于执行时目标对象的实际类型。
于 2012-09-25T16:54:50.047 回答