在 LTS 版本的 Java (Java 17) 中,我们第一次有了sealed
关键字,简而言之,我们可以限制层次结构:
public abstract sealed class Person
permits Employee, Manager {
//...
}
如果我想创建一个扩展Person
基类的新子类,我也必须修改基类。这是否违反了开闭原则?
在 LTS 版本的 Java (Java 17) 中,我们第一次有了sealed
关键字,简而言之,我们可以限制层次结构:
public abstract sealed class Person
permits Employee, Manager {
//...
}
如果我想创建一个扩展Person
基类的新子类,我也必须修改基类。这是否违反了开闭原则?
开闭原则不是物理定律,而只是在某些情况下可能有用的指导方针。另一个有用的原则,来自 Effective Java,是“为扩展而设计,否则禁止它”。(另外:“更喜欢组合而不是继承”。)我个人发现来自 Effective Java 的指导比开放封闭原则有用得多。为扩展设计类充满了权衡,通常是有问题的。
密封类可以被认为是最终类的泛化,只是应用于不同的粒度级别。以前,禁止扩展仅适用于具体类 ( final
),但现在它适用于整个层次结构。
但是,问题的前提——“如果我想添加……”——本身就是有问题的。密封类是一种机制,它允许 API 所有者通过控制抽象的所有实现(或通过限制对特定扩展点的扩展)来维护其 API 的完整性。API 所有者已经设计并实现了假设的层次结构有一组固定的实现;“添加”它然后真的变成“扔掉他们的设计并用不同的东西取而代之”。如果 API 没有为扩展而设计,那么事后猜测设计者的意图是有风险的。