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