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 }

 

以上這段代碼的運行結果:

 

Glyph() before draw()

 

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

第一行:OK,調用子類的構造函數時先調用基類的構造函數,這個可以理解。

第二行:很明顯,在基類的構造函數中調用的draw()方法被子類的draw()方法覆蓋了。但是radius為什么是0呢?為什么!原因據說是這樣的~

 在其他任何事物發生之前,將分配給對象的存儲空間初始化成二進制0

也就是說,我調用draw()的時候,我們只是有了radius這個對象,然而程序還沒進行到給這個對象賦值為1(見13行)??!?

第四行: 很好理解,前面做了那么多事之后,終於執行到子類的構造函數了。。這里面一定又發生了很多。。

 

然而,你以為這一切就這么簡單嗎?不。你試一下把基類的void draw()方法變成 private void draw()方法,那么有趣的事情發生了

運行結果變成了:

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM