设计构建器的规则

来源:互联网 发布:ubuntu 查看显卡驱动 编辑:程序博客网 时间:2024/05/16 14:02

设计构建器时一个特别有效的规则:用尽可能简单的方法使对象进入就绪状态;如果可能避免调用任何其他方法,在构建器中唯一能安全调用的就是在基础类中具有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) 调用衍生类构建器的主体。


原创粉丝点击