你的位置:首页 > 软件开发 > Java > 【Thinking in Java】编写构造器时应注意:尽量避免调用其他方法

【Thinking in Java】编写构造器时应注意:尽量避免调用其他方法

发布时间:2015-08-06 18:00:12
最近重温了《Thinking in Java》,发现了一个让我为之兴奋的知识漏洞,必须得分享一下。  上一篇的《Java类初始化的过程》的随笔中,那个初始化顺序并不完整。初始化的实际过程是:  在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的0;  如上一篇的《Ja ...

  最近重温了《Thinking in Java》,发现了一个让我为之兴奋的知识漏洞,必须得分享一下。

  上一篇的《Java类初始化的过程》的随笔中,那个初始化顺序并不完整。初始化的实际过程是:

    1.   在其他任何事物发生之前,将分配给对象的存储空间初始化成二进制的0;
    2.   如上一篇的《Java类初始化的过程》那样:父类的static成员变量和方法-->该类的static变量和方法-->开始实例化-->父类的普通成员变量和方法-->父类的构造方法-->该类的普通成员变量和方法-->该类的构造方法-->实例化结束

  然而,我们知道,当子类Sub继承了父类Sup、并重写了父类的方法draw()后,我们即使向上转型为父类(即Sup sup=new Sub()),当我们调用sup.draw()方法的时候,它实际上调用的是Sub的draw方法。这里就有个坑了!

  如果在父类的构造方法里调用draw()方法,从逻辑上,我们以为是调用父类的draw()方法,而实际上,即使在父类的构造器以内,Java编译器让它调用的还是子类的draw()方法。

  我们用一个例子来展示一下:

  

public class Glyph {  Glyph(){    System.out.println("Glyph before draw()");    draw();     //逻辑上本应该调用本类的draw(),然而结果不是    System.out.println("Glyph after draw()");  }  void draw(){    System.out.println("Glyph.draw()");  }}public class RoundGlyph extends Glyph{  private int radius=1;  public RoundGlyph(int r) {    radius=r;    System.out.println("RoundGlyph.RoundGlyph(),radius="+radius);  }  @Override  void draw() {    System.out.println("RoundGlyph.draw(),radius="+radius);  }}public class PolyConstructors {  public static void main(String[] args) {    new RoundGlyph(5);  }}

原标题:【Thinking in Java】编写构造器时应注意:尽量避免调用其他方法

关键词:JAVA

*特别声明:以上内容来自于网络收集,著作权属原作者所有,如有侵权,请联系我们: admin#shaoqun.com (#换成@)。