设计构建器的规则

设计构建器时一个特别有效的规则:用尽可能简单的方法使对象进入就绪状态;如果可能避免调用任何其他方法,在构建器中唯一能安全调用的就是在基础类中具有final属性的那些方法,(也可以是被private 修饰的方法,因为被private修饰的方法自动具有final的属性),这些方法不能被覆盖,所以不会出现下面的情况.

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(
"RoundGlyph.RoundGlyph(), radius = "
+ radius);
}
void draw() {
System.out.println(
"RoundGlyph.draw(), radius = " + radius);
}
}
public class PolyConstructors {
public static void main(String[] args) {
new RoundGlyph(5);
}
}


在Glyph 中,draw()方法是“抽象的”(abstract),所以它可以被其他方法覆盖。事实上,我们在
RoundGlyph中不得不对其进行覆盖。但 Glyph构建器会调用这个方法,而且调用会在RoundGlyph.draw()中
止,这看起来似乎是有意的。但请看看输出结果:
Glyph() before draw()
RoundGlyph.draw(), radius = 0
Glyph() after draw()
RoundGlyph.RoundGlyph(), radius = 5
当Glyph 的构建器调用 draw()时,radius 的值甚至不是默认的初始值1,而是 0。这可能是由于一个点号或
者屏幕上根本什么都没有画而造成的。这样就不得不开始查找程序中的错误,试着找出程序不能工作的原
因。
前一节讲述的初始化顺序并不十分完整,而那是解决问题的关键所在。初始化的实际过程是这样的:
(1) 在采取其他任何操作之前,为对象分配的存储空间初始化成二进制零。
(2) 就象前面叙述的那样,调用基础类构建器。此时,被覆盖的draw()方法会得到调用(的确是在
RoundGlyph构建器调用之前),此时会发现 radius的值为 0,这是由于步骤(1)造成的。
(3) 按照原先声明的顺序调用成员初始化代码。
(4) 调用衍生类构建器的主体。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值