---恢复内容开始---
public class Program6 {
public static void main(String[] args) {
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)); //AA
System.out.println("⑵ " + a1.show(c)); //AA
System.out.println("⑶ " + a1.show(d)); //AD
System.out.println("⑷ " + a2.show(b)); //BA
System.out.println("⑸ " + a2.show(c)); //BA
System.out.println("⑹ " + a2.show(d)); //AD
System.out.println("⑺ " + b.show(b)); //BB
System.out.println("⑻ " + b.show(c)); //BB
System.out.println("⑼ " + b.show(d)); //AD
}
}
class A {
public String show(D obj) {
return ("A and D");
}
public String show(A obj) {
return ("A and A");
}
}
class B extends A {
public String show(B obj) {
return ("B and B");
}
public String show(A obj) {
return ("B and A");
}
}
class C extends B {
}
class D extends B {
}
这个代码源于别人,但是讲的不太清楚 ,在这里记下自己的感悟,防止以后忘记。
正文:
第一个AA: A类对象调用A中方法,然而并没有 B类对象作为参数的方法,那么找B的上个类,有一个A的对象的方法 所以为AA
第二个AA:同样的,调用A类中的方法,没有以C类作为参数的方法,但是有A类的 为C 的父类的父类,所以打印AA
第三个AD:因为其中有D类对象作为参数的方法,所以输出AD
第四个:父类引用指向子类对象,首先调用的是 对象的方法 也就是B类中的,那么问题来了,为什么不直接使用B类对象作为参数的方法呢,
是因为由于向上转型,它只能访问父类中拥有的方法和属性,而对于不存在的方法,不能使用,意思就是只能使用重写的方法或者父类的方法。详情看下方
所以是BA;
第五个:BA,同上,虽然 C类继承B类 ,但是这点只能调用父类中存在的方法,没有以C类对象作为参数的方法,所以只能将C类作为A类,所以也是BA
第六个:AD ,同上,因为父类中 直接有D作为参数的方法,所以 AD
第七个:BB ,调用B类中以B类对象所谓参数的方法,所以BB
第八个:BB, 因为A B C 类中都没有 以C类对象作为参数的方法,所以C类变为B类,在B类中有 以B类作为参数的方法,(注:如果这点还找不到的话,就会将C类看做A类)并且执行B类的 BA, 为什么不是AA呢 因为覆盖掉了
第九个:AD:以D 对象作为参数的方法 存在,所以执行A类的, PS:这点我是这样理解的,就是一个类继承一个类的话,父类的方法没有覆盖调的话都会继承过去,这就是为什么 如果要初始化子类,一定会先加载父类。
多看看,挺有意思的题。
我们知道,向上转型时,用父类引用执行子类对象,并可以用父类引用调用子类中重写了的同名方法。但是不能调用子类中新增的方法。
在代码的编译阶段,编译器通过声明对象的类型(即引用本身的类型)在方法区中该类型的方法表中查找匹配的方法(最佳匹配法:参数类型最接近的被调用),如果有则编译通过。(这里是根据声明的对象类型来查找的,所以此处是查找Father类的方法表,而Father类方法表中是没有子类新增的方法的,所以不能调用。)
来源于百度百科,搜索 动态绑定
如有不正,请指出。