封类 in Java 17、开闭原则

Sealed classes in Java 17, and the open-closed principle

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

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

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

开闭原则不是物理定律,而只是在某些情况下可能有用的准则。另一个有用的原则来自 Effective Java,是“为扩展而设计,否则禁止它”。 (还有:“比起继承更喜欢组合”。)就我个人而言,我发现 Effective Java 的指导比开闭原则更有用;为扩展设计 类 充满了权衡,通常是有问题的。

Sealed 类 可以被认为是 final 类 的概括,只是应用于不同的粒度级别。以前,禁止扩展仅适用于具体 类 (final),但现在它适用于整个层级。

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