Java密封类:精准控制继承关系
在面向对象设计中,继承的开放性有时会带来意料之外的问题。Java 15引入的密封类(Sealed Classes)为此提供了优雅的解决方案,让我们能够精确控制哪些类可以继承自某个父类。
什么是密封类?
密封类通过sealed关键字声明,并使用permits子句明确指定允许继承的子类。这种机制在编译时就能确保继承关系的可控性。
public abstract sealed class Shape
permits Circle, Rectangle, Triangle {
public abstract double area();
}
public final class Circle extends Shape {
private final double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
核心优势
- 增强类型安全:编译器能检查所有 permitted 子类,避免遗漏 case
- 清晰的设计意图:明确表达哪些类属于某个继承体系
- 更好的模式匹配:为未来switch表达式的模式匹配铺平道路
使用规则
- 子类必须是
final、sealed或non-sealed - 所有 permitted 子类必须可访问且直接扩展密封类
- 同一个模块或包内才能继承
密封类特别适用于定义代数数据类型(ADT),如表达式树、状态机等场景。它让Java的类型系统更加严谨,帮助开发者构建更健壮、更易维护的代码结构。
通过这一特性,Java在保持向后兼容的同时,继续朝着更安全、更表达力的方向演进。