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這個小妖精啊,也不是個省油的燈,想要學明白還差得遠啊~~~遠遠遠呀!! 

相關文章
相關標籤/搜索