解决方案 »

  1.   

    我覆盖后的输出结果,我按照内存图的理解,应该是输出
    Father show...0
    Sons's Constructor run...8
    Father show...8
    才对,就是不能理解从内存角度分析的结果为什么不对,
    图中的三块内存区域分别是,左上是栈内存,右上是堆内存,下边是方法区
      

  2.   

    你在 Debug 模式下单步执行就知道了,那个 int number = 3是在类的构造方法之前就执行的。
    所以到了构造方法中这些成员变量已经有值了。当然了,如果你在父中构造方法中调用覆盖的子类的 show 方法,那么子类中的 number 这个时候还没有初始化,因此子类的 show 在被父类的构造方法调用时它得到的 this.number 就是0 而不是8。
      

  3.   

    在每一行下断点,然后 debug 它。以前我也没注意这个初始值的问题,后来是在 debug 过程中发现初始值的赋值后才进到构造方法中了。
      

  4.   

    嗯,这些东西还是自己调试运行理解的会更深刻。
    可以在各个位置进行输出
    父类{//父类代码块} 构造函数 属性值
    子类{//子类代码块} 构造函数 属性值
    看看java对类加载,先运行哪些
      

  5.   

    我也有个问题,为什么在初始化Fahter进入构造函数的时候调用的是Sons的show()方法啊?这样的话在开发过程中使用继承会不会出现好多问题啊?
      

  6.   

    这本来就是多态的概念,当你打算在构造函数中使用可能被覆盖的方法,这本来就表示,这个被覆盖的方法不应该与状态之间的关联如此密切,(比如,最好是它不要使用要求在构造方法中初始化的成员变量),或者你在访问过程上需要明确的思考是用成员变量名访问它还是用 getter/setter 方法它,总之,这是设计的决策问题,只要认真思考过,并且对特定的约定之处写在文档中就没有什么疑问,毕竟别人打算使用你的 API 的第一步应该是看 API 文档而不是猜测。
      

  7.   

    我想问的是,为什么Sons sons = new Sons();
    sons.show();
    如果show方法没有在子类中覆盖,那么此时sons.show();其实访问的是父类中的show方法,那么访问父类中的show方法时,show方法里面访问的number为什么是父类的成员变量,而不是子类的成员变量呢?因为此时的this指向的对象,其里面存放的成员变量应该是this.number应该等于8,super.number应该等于3。难道我要理解此时new出来的对象类型是Father类型的?
      

  8.   

    现在show 是父类的,这个 number 就解释成父类的。这些是在编译时确定使用谁的方法和变量,不是等到运行时。你提到的 number 解释成 this.number 是在暗示在运行的时候。
      

  9.   

    代码有个很明显的问题,一个类里面不只能有一个public么
      

  10.   

    Quote: 引用 11 楼 humanity 的回复:

    那把这句话改一下:
        用谁的方法就找和谁相关的成员变量。这正是我无法从内存图的角度去理解的内容。
      

  11.   

    在java中只有普通方法(除static 和 private之外)的调用是多态的,而域的访问是前期绑定而不是动态绑定的。也就是说编译上面的代码后,在内存中son同时拥有两个版本的number,一个从基类继承而来,另一个则为默认成员,当你没有在son中覆盖show方法时,很明显son.show调用的是基类版本的show方法,由于域是前期绑定的,也就是在编译期决定了基类show方法;中的number版本是基类版本的number。显然,在Son中覆盖了show后又是另一回事了
      

  12.   


    成员变量应该是前期绑定的,普通方法(非static和final)才是动态绑定的