java密封抽象类通过sealed+permits精确控制继承,仅允许列出的同包/同模块子类继承,且每个子类必须用final/sealed/non-sealed明确修饰,配合抽象方法保障类型穷尽性。

Java 中的密封抽象类(sealed abstract class)通过 sealed 关键字 + permits 子句实现对子类继承的精确控制——它不是“禁止继承”,而是“只允许列出的类继承”,且每个子类必须明确声明自己的继承策略。
必须显式声明允许的直接子类
密封抽象类不能省略 permits,后面紧跟用逗号分隔的、**所有且仅有的直接子类名**。这些子类必须与密封类在同一个包(未模块化项目)或同一模块(模块化项目)中。
- 编译器会强制校验:任何未出现在
permits列表中的类,即使写extends也会报错 - 子类名必须是已声明的类,不能是未定义的占位符
- 例如:
public sealed abstract class PaymentMethod permits CreditCard, Alipay, WechatPay { ... }
每个子类必须用 final / sealed / non-sealed 明确修饰
这是密封体系的强制约定,三者语义不同,不可省略:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
final class CreditCard extends PaymentMethod:彻底终止继承,不能再有子类 -
sealed class Alipay extends PaymentMethod permits AlipayCN, AlipayHK:自身也是密封类,继续限制下级子类 -
non-sealed class WechatPay extends PaymentMethod:开放该分支,允许任意类继承WechatPay
抽象方法与具体实现的配合
密封抽象类常配合抽象方法定义契约,而子类负责具体实现。编译器能据此保障类型穷尽性:
- 子类若为
final,必须提供所有抽象方法的具体实现 - 子类若为
sealed,可保留部分抽象方法供其子类实现 - 搭配
switch表达式时,编译器可检查是否覆盖了全部permits子类,避免遗漏
注意可见性与模块边界
密封关系依赖编译期可见性约束:
- 如果项目使用模块系统(
module-info.java),需确保子类所在模块能读取密封类所在模块 - 跨模块继承不被允许,除非显式声明
exports和requires - 不推荐将密封类设为
public后放在默认包或随意暴露——这会削弱密封意图
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










