优先级公式:
this.show(object)>super.show(object)>this.show((super)object)>super.show((super))
题目:
问以下代码的执行结果
public class Test{
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)); // 1
System.out.println(a1.show(c)); // 2
System.out.println(a1.show(d)); // 3
System.out.println(a2.show(b)); // 4
System.out.println(a2.show(c)); // 5
System.out.println(a2.show(d)); // 6
System.out.println(b.show(b)); // 7
System.out.println(b.show(c)); // 8
System.out.println(b.show(d)); // 9
}
}
class A{
public String show(D obj){//3 6 9
return ("A and D");
}
public String show(A obj){//1
return ("A and A");
}
public String show(C obj){//2
return ("A and C");
}
}
//A->B->C
//A->B->D
class B extends A{
public String show(B obj){//7
return ("B and B");
}
public String show(A obj){//4
return ("B and A");
}
public String show(C obj){//5 8
return ("B and C");
}
}
class C extends B{}
class D extends B{}
答案:
- A and A
- A and C
- A and D
- B and A
- B and C
- A and D
- B and B
- B and C
- A and D
分析
借助这道题,讲一下这个公式"this.show(obj) > super.show(obj) > this.show((super)obj) > super.show((super)obj)“的用法:
第一行: System.out.println(a1.show(b));
先看第一级this.show(obj),这时的this就是指对象本身,也就是a1的类"A”,在该类中寻找show方法,根据参数是类B的实例对象,发现类A中找不到调用类B的实例对象的方法,这时再看第二级super.show(obj),这个super是指a1的父类,可是a1的父类是java中的最初类Object类,可是Object类没有show方法,因此第二级也pass掉。第三级,this.show((super)obj),this亦是指对象本身,此时该对象的实参被强制转换为父类,故原式变为a1.show(a),在类A中有参数为class A类型的show函数,故此处返回为"A and A".
第二行:System.out.println(a1.show©);
先看第一级this.show(obj),a1的type是类A,故类A中能找到参数为类C的函数,故此处返回为"A and C".
第三行:System.out.println(a1.show(d));
规律同第一行,也是在类A中能直接找到参数为类D类型的方法,故直接返回"A and D".
第四行: System.out.println(a2.show(b));
a2的初始化是一个上转型的过程. 先看第一级this.show(obj),show函数在类中发生重载,a2首先查看类B中被复写的show函数,发现没有参数为类B类型的show()函**[note:由于上转型只能调用子类中复写父类的函数,因此由于B类中public String show(B obj)方法在父类A中没有出现过,该方法不会被调用]**,因此看第二级super.show(obj),很显然,在类A中也找不到形参为类B的show函数,接着查看第三级,this.show(super(obj)),实参b将被强制转换为A类参数,故此时a2.show(b)变成了a2.show(a),在类B中能找到形参为类A的show函数,故返回为"B and A".
第五行: System.out.println(a2.show©);
第一级:this.show(obj):由于在类B中找到了复写其父类A且也具有形参为C类的show()函数,故直接返回"B and C".
第六行:System.out.println(a2.show(d));
第一级:this.show(obj):在类B中找不到形参为类D的show()函数,故在父类A中寻找(因为a2属于类B的上转型,它固然有父类A的函数调用权),找到了形参是类D的show()函数,故直接返回"A and D"
第七行:System.out.println(b.show(b));
第一级this.show(obj),此时的this代指类B的实例对象b,在类B中存在形参为类B的show()函数,故直接返回"B and B".
第八行:System.out.println(b.show©);
规律同第七行,返回"B and C".
第九行:System.out.println(b.show(d));
第一级:this.show(obj),类B找不到形参为类D的show()函数,故直接转第二级super.show(obj),类B的父类是类A,在类A中寻找到了形参为类D的show()函数,故直接返回"A and D".