java中构造函数的调用顺序

 1  class Glyph {
 2      void draw() {
 3         System.out.println("Glyph.draw()");
 4     }
 5     Glyph() {
 6         System.out.println("Glyph() before draw()");
 7         draw();
 8         System.out.println("Glyph() after draw()");
 9     }
10 }
11 
12  class RoundGlyph  extends Glyph {
13      private  int radius = 1;
14 
15     RoundGlyph( int r) {
16         radius = r;
17         System.out.println("RoundGlyph.RoundGlyph(). radius = " + radius);
18     }
19 
20      void draw() {
21         System.out.println("RoundGlyph.draw(). radius = " + radius);
22     }
23 }
24 
25  public  class Main {
26 
27      public  static  void main(String[] args) {
28          new RoundGlyph(5);
29 
30     }
31 
32 }

 

以上这段代码的运行结果:java

 

Glyph() before draw()

 

RoundGlyph.draw(). radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(). radius = 5

第一行:OK,调用子类的构造函数时先调用基类的构造函数,这个能够理解。函数

第二行:很明显,在基类的构造函数中调用的draw()方法被子类的draw()方法覆盖了。可是radius为何是0呢?为何!缘由听说是这样的~spa

 在其余任何事物发生以前,将分配给对象的存储空间初始化成二进制0code

也就是说,我调用draw()的时候,咱们只是有了radius这个对象,然而程序还没进行到给这个对象赋值为1(见13行)??!?对象

第四行: 很好理解,前面作了那么多事以后,终于执行到子类的构造函数了。。这里面必定又发生了不少。。blog

 

然而,你觉得这一切就这么简单吗?不。你试一下把基类的void draw()方法变成 private void draw()方法,那么有趣的事情发生了it

运行结果变成了:class

Glyph() before draw()
Glyph.draw()
Glyph() after draw()
RoundGlyph.RoundGlyph(). radius = 5


很好,对于这个问题,答案是:构造函数

只有非private方法才能够被覆盖。即,子类中,咱们觉得的覆盖private方法对子类来讲是一个新的方法而非重载方法。所以在子类中,新方法最好不要与积累的private方法采起同一名字,以避免误解。二进制

 

那么若是把基类中的void draw()方法变成public void draw()方法呢?嗯,这时,程序会报错,须要把子类中的void draw()方法也变成public void draw()方法就OK了,效果和void draw()相同。

 

java这个小妖精啊,也不是个省油的灯,想要学明白还差得远啊~~~远远远呀!! 

相关文章
相关标签/搜索