JAVA继承与多态_方法调用优先级

优先级公式:

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{} 

答案:

  1. A and A
  2. A and C
  3. A and D
  4. B and A
  5. B and C
  6. A and D
  7. B and B
  8. B and C
  9. 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".

你可能感兴趣的:(JAVA继承与多态_方法调用优先级)