java抽象类通过abstract方法设编译“铁闸”,强制子类实现核心逻辑;用final模板方法锁死流程,如process()调用validate→docore→notify;构造器校验参数并初始化final字段;区分abstract方法(必须实现)与空protected方法(可选扩展)。

Java 中抽象类通过编译期强制机制约束子类必须实现特定逻辑,核心是 abstract 方法 + 抽象类声明 + 模板方法协同。不靠文档、不靠约定,而是让代码写完就过不了编译——这才是真正可靠的约束。
用 abstract 方法设下编译“铁闸”
在抽象类中声明没有方法体的方法,就是最直接的强制手段:
- 必须用
abstract修饰,且不能有{}或任何实现逻辑 - 访问修饰符只能是
public或protected(private子类看不见,static/final与重写语义冲突) - 子类若是具体类(非
abstract),未实现该方法就会报错:
class Xxx must either be declared abstract or implement abstract method … - 建议子类实现时加上
@Override,避免因参数类型写错(如用了不同包的List)导致“看似重写、实则新增”
靠 final 模板方法锁死执行流程
只卡“有没有写”,不管“怎么调”,容易被绕过。真正落地要靠模板方法把主干流程焊死:
- 定义一个
public final void process(),内部按固定顺序调用:validate() → doCore() → notify() - 其中
doCore()设为protected abstract,其余为父类已实现的具体方法 -
final保证子类无法覆盖整个流程,也不能跳过校验或通知环节 - 子类只需专注
doCore()这一段,不用重复写事务控制、日志记录等通用逻辑
用构造器和字段守住初始化底线
抽象类虽不能 new,但它的构造器会在子类实例化时自动执行,这是施加约束的第二道防线:
- 可在构造器中校验必要参数(如配置不能为空、超时值不能为负),不合规直接抛异常
- 可初始化
final字段(如不可变上下文、共享连接池),确保一创建就有稳定状态 - 切忌在构造器里调用抽象方法——此时子类字段尚未初始化,极易触发
NullPointerException
区分“必须实现”和“可选扩展”
不是所有扩展点都要强制。抽象类可同时提供两类钩子:
-
abstract方法:子类不实现就编译失败,用于核心差异点(如calculatePrice()、buildRequest()) - 空的
protected具体方法:如onSuccess()、beforeCleanup(),子类按需重写,不重写也不影响编译和运行 - 命名建议带语义前缀(
onXXX/afterXXX),便于识别扩展意图
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











