Java周二生效! 继承或禁止继承的设计和文档类。

在上一章的回顾中,我们谈到了实现继承的危险。 承认这一点是有时实现继承是正确的做法。 今天我们要讨论的就是这些情况。 如何帮助实现继承成功。

首先要知道的是,您应该记录覆盖每个可覆盖方法(即非最终的,公共的或受保护的方法)的影响。 这意味着您必须记录何时类在内部使用其自己的方法,以及在什么地方重写方法可能导致意外的结果。 在上一章的回顾中,我们看到了一个例子。 其他应该记录的内容是是否可以从静态上下文,后台线程等调用此方法。任何可能影响实现者实现方法的方式。

从Java 8开始,JavaDoc已添加了一项新功能来简化此操作。 此功能在文档中增加了一个新部分,专门用于简化此文档,@implspec。 让我们看一下在java.util.AbstractCollection的去掉 method的JavaDoc.

{@inheritDoc}

This implementation iterates over the collection looking for the specified
element.  If it finds the element, it removes the element from the collection
using the iterator's remove method.

Note that this implementation throws an UnsupportedOperationException if the
iterator returned by this collection's iterator method does not implement the
remove method and this collection contains the specified object.

这清楚地表明,改变迭代器作品会影响这个去掉函数的行为。 想象一下,当我们覆盖了加和加All在功能哈希集在我们之前的评论中,我们可能已经知道加All函数称为加功能。

“但是,凯尔,”您说,“我们的文档不应谈论函数的功能,而不是函数的功能。” 您是正确的,这就是良好的API文档做法所建议的。 不幸的是,由于实现继承破坏了封装,因此为了便于子类的实现,我们需要编写此“如何”文档,以便子类的实现者知道如何做到这一点,并且不会因意外行为而失明。

您可能还需要创建受保护的方法,以便实现者可以有效地实现其子类。 这导致实现中的额外工作,并可能需要更多代码来简化此行为。 这些方法应该存在于受保护的访问级别,而不是上市 access level in order to avoid polluting the 上市 API.

那你做什么私人的你做什么受保护的? 这将需要一些思考和尝试。 不幸的是,没有公式。 确保可以访问所需的内容而不访问不需要的内容的最佳方法是编写一些子类并查看其感觉。 音高有效的Java使您为扩展编写的每个类都创建三个子类,并让这些子类之一由超类的作者以外的其他人编写,然后再发布。 发布后,您几乎不得不保留刚开始的实现。

您也不能从构造函数中调用可重写的方法。 这可能会导致奇怪的故障,而这种故障最好避免。 这是因为该方法将在子类的构造函数运行之前被调用。 让我们来看一个例子。

public class Super {
  public Super() {
    overrideMe();
  }

  public void overrideMe() {}
}

public class Sub extends Super {
  private final Instant instant;

  public Sub() {
    this.instant = Instant.now();
  }

  @Override
  public void overrideMe() {
    System.out.println(instant);
  }

  public static void main() {
    Sub sub = new Sub();
    System.out.println(sub.overrideMe());
  }
}

运行此代码,您将看到标准输出的两个输出。 一个是空值一个是瞬间。 这是因为OverrideMe从调用超类的构造函数。 最疯狂的部分是对于相同的输出,我们得到两个不同的值最后变量。

要记住的其他一些事情是实施可克隆的和可序列化在为继承而创建的这些类之一上实现时,可能会很危险。 在讨论这一章中可以找到一些技巧可克隆的减轻这种风险。 基本上可以归结为不调用可重写方法以完成可克隆的工作。

如您所见,这是很多工作。 它的确是。 这就是为什么我们的默认操作应该是除非确实需要,否则不创建用于继承的类。 那么我们如何防止这种情况呢? 有两种主要的实现方法。

  1. 上课最后将构造函数设为私有或包私有。

我还将承认书中没有的另一点。 这种安全性在很大程度上取决于代码的受众。 如果您是将由与您没有直接联系的各种项目使用的类的库作者,则说明您是在一家大公司中,而您的代码已被您无法控制的其他各种组使用,或者 您正在编写将在世界范围内使用的开源库,本章中的建议非常相关。 但是,如果您是微服务开发人员,而您的代码将仅以较小且集中的方式在您自己的团队中使用,我认为您可以放宽其中的一些要求。 是的,我们仍然应该使用可靠的工程实践来编写良好,安全的代码,但是如果需要的话,您也可以更改使用方代码。

因此,存在一些有关如何创建为继承而构建的类的提示和技巧。 这是很多工作,但是如果我们花时间做正确的事,我们可以为其他人以更安全的方式建立坚实的基础而告终。

from: https://dev.to//kylec32/effective-java-tuesday-design-and-document-classes-for-inheritance-or-else-prohibit-it-1751

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值