撰写构造函数时,“尽可能简单的让对象进入正确状态。如果可以的话别调用任何函数”,构造函数中唯一可以安全调用的函数时“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)。