您的位置 首页 java

Effective Java代码规则之十九:设计继承并提供文档否则禁止继承

1、什么是设计继承并提供文档

对于需要被继承的类而言,我们要进行专门设计,并且提供文档说明。

2、为什么要设计继承并提供文档否则禁止继承

Effective Java代码规则之十八条规则提醒过我们继承的危害性,如果不好好设计可继承类并且提供文档说明,我们就应该禁止该类被继承。

3、如何设计继承并提供文档

3.1、设计继承类的约束

  • 类必须通过某种形式提供适当的钩子

类必须以精心挑选的受保护的(protected)方法的形式,提供适当的钩子( hook ),以便进入其内部工作中。例如,以java.util.AbstractList中的removeRange方法为例:

protected void removeRange(int fromIndex, int toIndex) {
 ListIterator<E> it = listIterator(fromIndex);
 for (int i=0, n=toIndex-fromIndex; i<n; i++) {
 it.next();
 it.remove();
 }
 }
 

提供该方法的唯一目的在于,使子类更易于提供针对子列表( sublist )的快速clear方法。如果没有removeRange方法,当在子列表( sublist )上调用clear方法时,子类将不得不用平方级的时间来完成它的工作。否则,就得重新编写整个subList机制。

  • 必须在发布类之前先编写子类对类进行测试
  • 构造器决不能调用可被覆盖的方法

超类的构造器在子类的构造器之前运行,所以,子类中覆盖版本的方法将会在子类的构造器运行之前就先被调用 。如果该覆盖版本的方法依赖于子类构造器所执行的任何初始化工作,该方法将不会如预期般的执行。

  • 对于实现了Cloneable接口的类,在clone方法中不能调用可被覆盖的方法

对于clone方法,覆盖的方法则是在子类的clone方法有机会修正被克隆对象的状态之前先被运行。

  • 对于实现了Serializable接口的类,在readObject方法中不能调用可被覆盖的方法

对于readObject方法,覆盖的方法将在子类的状态被反序列化(deserialized)之前先被运行。

  • 对于实现了Serializable接口的类,readResolve和writeReplace方法必须是protected的

如果这些方法是私有的,那么子类将会不声不响地忽略掉这两个方法。

3.2、如何提供文档说明

  • 该类的文档必须精确地描述覆盖每个方法所带来的影响
  • 对于可覆盖的方法,它的文档中要说明它们调用了自己的哪些public或protected类型的方法(非final),并说明调用顺序和每次调用的作用
  • 文档编写完成,并发布新版本之后,后续的版本不能违背文档中的细节

4、如何禁止继承

  • 把这个类声明为final的
  • 将类的构造器申明为私有或包级私有类型,然后用静态工厂获取实例

5、最佳实践

在实际工作中,专门为了继承而设计类并且建立文档说明是一件很辛苦的工作,我们应该尽量使用复合来代替继承。

#IT极客老兵#

文章来源:智云一二三科技

文章标题:Effective Java代码规则之十九:设计继承并提供文档否则禁止继承

文章地址:https://www.zhihuclub.com/176581.shtml

关于作者: 智云科技

热门文章

网站地图