学习继承时的疑惑

 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的方法来打印。 

暂时先到这里吧,如果有什么新的理解的话后续会再更新。

posted @ 2019-04-09 15:32  末夏始秋  阅读(119)  评论(0编辑  收藏  举报