1.类定义:
class A {
public String show(D obj) {
return ("A - D");
}
public String show(A obj) {
return ("A - A");
}
}
class B extends A {
public String show(B obj) {
return ("B - B");
}
public String show(A obj) {
return ("B - A");
}
}
class C extends B {
}
class D extends B {
}
2.调用执行:
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println("⑴ " + a1.show(b)); //A-A
System.out.println("⑵ " + a1.show(c)); //A-A
System.out.println("⑶ " + a1.show(d)); //A-D
System.out.println("⑷ " + a2.show(b)); //B-A
System.out.println("⑸ " + a2.show(c)); //B-A
System.out.println("⑹ " + a2.show(d)); //A-D
System.out.println("⑺ " + b.show(b)); //B-B
System.out.println("⑻ " + b.show(c)); //B-B
System.out.println("⑼ " + b.show(d)); //A-D
3:分析:
a1.show(b));Class A 中没有show(B obj),B转向B的父类A,执行A show(A obj)--->return "A - A"
a1.show(c));Class A 中没有show(C obj),C转向C的父类B,Class A 中没有show(B obj),再转向父类A,执行A show(A obj)--->return "A - A"
a1.show(d));Class A 中有show(D obj)执行A show(D obj)--->return "A - D"
这个比较特殊:A a2 = new B();父类声明,子类实例,你应该把a2当作子类重写完后的父类看,注意只有父类的方法。
a2.show(b));Class A 中没有show(B obj),B转向B的父类A,执行A show(A obj),A的show 方法被重写,执行B show(A obj)--->return "B - A"
a2.show(c));Class A 中没有show(C obj),C转向C的父类B,Class A 中没有show(B obj),B转向父类A,执行A show(A obj),A的show 方法被重写,执行B show(A obj)--->return "B - A"
a2.show(d));Class A 中有show(D obj)执行A show(D obj)--->return "A - D"
b.show(b)); Class B 中有show(B obj)--->return "B - B"
b.show(c)); Class B 中没有show(C obj),Class B父类Class A 也没有show(C obj)给Class B 继承,C转向C的父类B,执行B show(B obj)--->return "B - B"
b.show(d)); Class B 中有继承了Class A 的show(D obj),执行A show(D obj)--->return "A - D"
总结:
System.out.println("⑷ " + a2.show(b));
这里有个陷阱,以为右边是一个new B(),所以就直接在B类中找方法,又因为参数是B,所以就以为是调用show(B obj)
而实际上程序运行的步骤是这样的:
1. 首先检查a2的静态类型是A类型,就在A类中找对应的方法,因为A中没有show(B obj), 但是B继承自A,所以找到了show(A obj).
2. 然后在根据a2的实际类型是B,再从B类中找到show(A obj)的重写方法
所以应该是调用B的show(A obj)
如果对第一点存在质疑,可以将A中的show(A obj)方法改成show(C obj),编译器直接就报错。没有找到适用的方法,说明是按A类型开始检查方法。