撰寫構造函數時,“盡可能簡單的讓對象進入正確狀態。如果可以的話別調用任何函數”,構造函數中唯一可以安全調用的函數時“base class中的final函數和private函數”,這樣的函數無法被重寫。
原因:看下列程序。
abstract class Glyph {
abstract void draw();
Glyph(){
System.out.println("Glyph() before draw()");
draw(); //注意這個函數,他的調用順序
System.out.println("Glyph after draw()");
}
}
class RoundGlyph extends Glyph{
int radius = 1;
RoundGlyph(int r) {
radius = r;
System.out.println{
"ToundGlyph.ToundGlyph(),radius = " + radius);
}
void draw(){
System.out.println("RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors{
public static void main(String args[]){
new RoundGlyph(5);
}
}
輸出的結果是:Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
我們看到在超類的構造函數中調用了一個抽象函數Draw(),這時radius尚未被初始化為1,所以其值為0。構造函數中不會為某個調用函數進行解析動態綁定,找出它隸屬的class,他的任務是對象從無到有,他最終調用的這個函數是位于他最終被覆寫的那個,而此時那個類還沒有完全初始化,這會造成災難性的后果。(出自JAVA編程思想 P239)。