学习继承时的疑惑
1 package com.hxy; 2 3 public class Fantasy { 4 public static void main(String[] args) { 5 A a = new A(); 6 a.b1(8); 7 } 8 } 9 10 class A extends B implements F{ 11 int a = 9; 12 13 public A(){ 14 15 } 16 17 @Override 18 public void b2(){ 19 System.out.println("Override b2?"); 20 } 21 } 22 23 class B extends C{ 24 int a = 10; 25 26 public B(){ 27 28 } 29 30 public void b1(int a){ 31 System.out.println(this.a); 32 this.b2(); 33 super.b2(); 34 } 35 36 @Override 37 public void b2(){ 38 System.out.println("Not Override?"); 39 }; 40 } 41 42 class C extends D{ 43 int a = 11; 44 45 @Override 46 public void b2() { 47 this.b2(); 48 super.b2(); 49 } 50 } 51 52 class D { 53 public void b2() { 54 System.out.println("D is here"); 55 } 56 } 57 58 interface F { 59 default void say() { 60 System.out.println("FF"); 61 } 62 63 static int doo(){ 64 return -1; 65 } 66 }
猜猜看,输出会是什么?
10 Override b2? Override b2? D is here
想了半天,也没想到为什么输出是这样。
我的推理如下(不知道对不对):
1. 数据域部分属于静态绑定,也就是在运行前(编译时)就确定好值的。所以this.a就是指的B中的a。如果B没有,就是B的父类C中的a......以此类推。
2. 方法属于动态绑定,由实际类型决定,如果没有实现,沿着继承链一直找下去直到找到为止。这里a属于A类的实例,由于A中没有b1方法, 所以到A的父类B类中找并找到了。
- 在调用this.b2()时,应该是这样的:B this = a; this. b2(); 那么结果显而易见,又会从A类开始找并且找到了A中重写的b2方法,按该方法打印。
- 在调用super.b2()时,调用的应该是B的父类C的b2方法。到了C, 又是this.b2()。则C this = a; this.b2(); 还是按A中的方法来打印。super.b2()则直接到D中的b2方法,这里已经没有任何this和super了,所以直接按照D的方法来打印。
暂时先到这里吧,如果有什么新的理解的话后续会再更新。