Effective Java 第17条:要么为继承而设计,并提供文档说明,要么就禁止继承

    xiaoxiao2023-10-21  28

    对于专门为了继承而设计并且具有良好文档说明的类而言,该类的文档必须精确地描述覆盖每个方法所带来的影响。该类必须有文档说明它可覆盖的方法的自用性。

    好的API文档应该描述一个给定的方法做了什么工作,而不是描述它是如何做到的。

    类必须通过某种形式提供适当的钩子,以便能够进入到它的内部工作流程中,这种形式可以是精心选择的受保护的方法,也可以是受保护的域,后者比较少见。

    对于为了继承而设计的类,唯一的测试方法就是编写子类。

    对于那些并非为了安全地进行子类化而设计和编写文档的类,要禁止子类化。

    如果认为必须允许从这样的类继承,一种合理的办法就是确保这个类永远不会调用它的任何可覆盖的方法,并在文档中说明这一点。

    如何编写为继承而设计的类? (1)对于public或是protected的方法(非final)或是构造器,在文档中要说明它们调用了哪些自己的public或是protected类型的方法(非final),并说明调用顺序,并说明每次调用的作用。 (2)文档编写完成,并发布新版本之后,后续的版本不能违背文档中的细节。 (3)构造器绝对不能调用可被覆盖的方法。 (4)对于实现了Cloneable接口的类,在clone方法中不能调用可被覆盖的方法。 (5)对于实现了Serializable接口的类,readResolve和writeReplace方法必须是protected的。 (6)对于实现了Serializable接口的类,在readObject方法中不能调用可被覆盖的方法。

    如何将类设计成不可继承的? 方法一:用final类型来申明这个类。 方法二:将类的构造器申明为private类型的,然后用静态工厂获取到这个类的实例。

    总结 要设计一个专门为继承而设计的类是十分困难的,所以能用复合就用复合,如果需要被继承的类没有实现类型接口,不能实现复合包装,并且该类还是需要被继承的,那么请不要在可覆盖的方法中调用其它可覆盖方法,或者将想要覆盖的父类方法拷贝一份出来到子类中,做成私有方法,然后用这个私有方法替代调用super.method()(method指的是方法名)。

    最新回复(0)