经典代码

class A {  
         public void show(D obj) {  
                System.out.println("A and D");
         }   
         public void show(A obj) {  
        	 System.out.println ("A and A");  
         }   
}
   
class B extends A{  
         public void show(B obj) {  
        	 System.out.println("B and B");  
         }  
         public void show(A obj) {  
        	 System.out.println("B and A");  
         }   
}  

class C extends B{}  
 
class D extends B{}

根据以上代码,写出下面代码运行的结果

A a1 = new A();  
A a2 = new B();  
B b = new B();  
C c = new C();   
D d = new D();   
a1.show(b);//1
a1.show(c);//2
a1.show(d);//3
a2.show(b);//4
a2.show(c);//5
a2.show(d);//6
b.show(b);//7
b.show(c);//8
b.show(d);//9

答案如下

A and A
A and A
A and D
B and A
B and A
A and D
B and B
B and B
A and D

答案分析

已知有以下的优先级

  • 优先级1:this.方法名(参数)
  • 优先级2:super.方法名(参数),这一点是因为子类从父类继承了方法。
  • 优先级3:this.方法名((super)参数)
  • 优先级4:super.方法名((super)参数)
    注意:如果本方法被子类覆盖,则调用子类的方法

总结:
当超类对象引用变量引用子类对象时,被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,但是这个被调用的方法必须是在超类中定义过的,也就是说被子类覆盖的方法。 (但是如果强制把超类转换成子类的话,就可以调用子类中新添加而超类没有的方法了)

具体解析

根据优先级做出解答:

  1. 第一行和第二行:b和c都是B和C的对象,他们的超类是A。this指的是A的对象。优先级1中因为没有B和C的类型的参数,所以看优先级2,也不满足,A没有超类(除了Object类),再看优先级三,刚好满足。所以输出为A and A ;

  2. 第三行:因为有满足D对象的参数,满足优先级1,所以输出A and D;

  3. 第四和第五行:这里有创建对象的多态,第一第二优先级都不满足,首先他满足第三优先级,但是被方法被重写,所以调用B类被重写的方法;

  4. 第六行:因为this代表的是A的对象。因为A类中偶对应的参数,满足第一优先级,所以输出为"A and D";

  5. 七八行:在创建对象时并没有多态,我们来考虑参数的多态,七行是符合优先级1的,八行符合优先级三;

  6. 第九行:因为B从A中继承了含有D类参数的方法,复合优先级二,所以输出"A and D"。

在此推荐另外一篇比较好的博客,值得一读~
博客链接

posted on 2021-02-07 17:40  Stephen_Hawking  阅读(44)  评论(0编辑  收藏  举报