今天来看提示十九:要么为继承而设计,并提供文档说明,要么就禁止继承。
之前说过继承会带来很多危险,所以这一章讨论了如何正确使用继承。
- 首先,这个类必须准确地描述重写每个方法带来的影响。 换句话说,该类必须文档说明可重写方法的自用性(self-use)。
- 文档必须指明方法调用哪些可重写方法,以何种顺序调用的,以及每次调用的结果又是如何影响后续处理。
- 调用可重写方法的方法在文档注释结束时包含对这些调用的描述。 这些描述在规范中特定部分,标记为「Implementation Requirements」,由 Javadoc 标签 @implSpec 生成。
为了继承而进行的设计不仅仅涉及自用模式的文档设计。为了使程序员能够编写出更加有效的子类,而无须承受不必要的痛苦,类必须以精心挑选的 protected 方法的形式,提供适当的钩子(hook),以便进入其内部工作中。关于hook这段,文中用了AbstractList 中的 removeRange 方法举例,但是我以前理解的hook是通过监听某段程序,插入一些操作。和这里的hook好像不是同一种东西,感觉这里更多的为了方便用户以后重写这个方法,来提供更高效的方法。但是如果子类能够有更快速的方法来实现这种操作,完全可以把方法放在子类自己内部,为什么要在父类上加上这个方法?为了让这个基类都能实现该方法?
测试为继承而设计的类的唯一方法是编写子类。经验表明,三个子类通常足以测试一个可继承的类。 这些子类应该由父类作者以外的人编写。
还有一些类必须遵守允许继承的限制。构造方法绝不能直接或间接调用可重写的方法。(因为超类的构造器在子类的构造器之前运行,如果子类中覆盖版本的方法依赖于子类构造器所执行的任何初始化工作,该方法将不会如预期般地执行)。Cloneable 和 Serializable 接口在设计继承时会带来特殊的困难。 对于为继承而设计的类来说,实现这些接口通常不是一个好主意。
禁止对在设计上和文档说明中都不支持安全子类化的类进行子类化。
总得看下来作者为了类的继承能够被正确使用制定了很多规则,但是对于我们系统来说或许不需要如此严格。感觉这些要求更多的是对那些需要提供给外部访问的代码,比如一些工具类或者第三方的类库,它们在编写的时候可能就需要这样的考虑。
网友评论