【问题标题】:Sealed classes in Java 17, and the open-closed principleJava 17 中的“新”密封类和开闭原则
【发布时间】:2022-01-10 16:02:08
【问题描述】:

在 LTS 版本的 Java (Java 17) 中,我们第一次拥有 sealed 关键字,简而言之,它使我们可以限制层次结构:

public abstract sealed class Person
    permits Employee, Manager {
 
    //...
}

如果我想创建一个扩展Person 基类的新子类,我也必须修改基类。这是否违反了开闭原则?

【问题讨论】:

  • 请注意,我们一直有final,这使我们可以限制层次结构。密封将其扩展到单个具体类之外。

标签: open-closed-principle sealed-class java-17


【解决方案1】:

开闭原则不是物理定律,而只是在某些情况下可能有用的指导方针。另一个有用的原则,来自 Effective Java,是“为扩展而设计,否则禁止它”。 (另外:“优先组合而不是继承”。)我个人认为来自 Effective Java 的指导远比开放封闭原则有用得多。为扩展设计类充满了权衡,通常是有问题的。

密封类可以被认为是最终类的泛化,只是应用于不同的粒度级别。以前,禁止扩展仅适用于具体类 (final),但现在可用于整个层次结构。

但是,问题的前提——“如果我想添加......”——本身就是有问题的。密封类是一种机制,它允许 API 所有者通过控制抽象的所有实现(或通过限制对特定扩展点的扩展)来维护其 API 的完整性。API 所有者已经设计并实现了假设的层次结构有一组固定的实现; “添加”它然后真的变成“扔掉他们的设计并用不同的东西取而代之”。如果 API 不是为扩展而设计的,那么事后猜测设计者的意图是有风险的。

【讨论】:

  • 因此,使用密封类可以表明应用程序的一部分不可扩展。当我写这个问题时,我正在考虑 Kotlin 中的密封类。在这种情况下,JetBrain 开发人员以不同的方式设计它们(也许他们已经考虑了这一原则)。在 Kotlin 中,您不必在基类中指定允许的子类列表。
  • 在最常见的情况下(当子类型与密封类型共同声明时),Java 编译器也可以推断出允许的子类型列表。
猜你喜欢
  • 2021-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-17
  • 1970-01-01
  • 2010-09-15
  • 2021-02-01
相关资源
最近更新 更多