程序例子
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");
}
public String show(D obj){
return ("B and D");
}
}
class C extends B{
}
class D extends B{
}
public class Duotai {
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("1--" + a1.show(b));
System.out.println("2--" + a1.show(c));
System.out.println("3--" + a1.show(d));
System.out.println("4--" + a2.show(b));
System.out.println("5--" + a2.show(c));
System.out.println("6--" + a2.show(d));
System.out.println("7--" + b.show(b));
System.out.println("8--" + b.show(c));
System.out.println("9--" + b.show(d));
System.out.println(a2.show(d));
System.out.println(a2.show(a1));
}
}
分析
1.前提:
对于A a =new a() 不需要分析,就是创建了一个变量引用a指向了类A。
对于A a =new B() 指生成了一个变量引用a指向了类B,但是值得注意的是,我们在堆中产生了一个new B(),在栈中生成了一个引用a,这个a指向了new B(),那么这样会导致什么结果呢?就是我们用A调用B的方法时候可能会遇到问题,例如A中有say()方法,B中没有,a.say(),可以;但是若B中有say(),A没有,那么很显然,a.say()根本没这个方法,也就没法调用;若是A,B都有say(),我们调用的时候就会涉及到多态了。
2.方法
很明显,前提中提到的AB都有say,调用时候会使用B类中的方法,很好理解,但是题目中的你会不会答对呢?
要是对了那你还看个jb,没对的话总结了一个诀窍可以帮助大家理解。
先把答案拿出来
1--A and A
2--A and A
3--A and D
4--B and A
5--B and A
6--B and D
7--B and B
8--B and B
9--B and D
B and D
B and A
再把诀窍给出来
继承链中对象方法的调用存在一个优先级:this.show(O)、super.show(O)、this.show((super)O)、super.show((super)O) 其中this就是声明类,不是后面的引用类A a =new B(),a.say(),this指A类,不是B类。
我们直接开始分析
继承关系 C,D->B->A
第一题:首先 A a1 = new A(); B b = new B();a1.show(b) ->实际上就是A.show(B)->在A中找show(B),无,找A.show(B.super),找到A.show(A)->输出A and A
123题同理
第四题 :首先 A a2 = new B(); B b = new B();a2.show(b)->this.show(B)即A.show(B),A中无此方法,找A.show(B.super),找到A.show(A)->但是此时A指向了B,并且B中重写了show(A),所以应该是B.show(A)->输出B and A。
其他题同理
3结论
所以我们要注意除了调用链之外,还有就是引用的类A是否被被引用类B重写了调用的方法say(),重写就要调用B.say(),没有的haul就是用A.say()。