抽象类通过abstract方法强制子类实现核心逻辑并用final模板方法锁定执行顺序,配合protected字段与构造器统一管理状态,预留钩子和工具方法提升复用性。

抽象类本身不完成业务逻辑,而是通过强制子类实现特定方法,把“做什么”定死,把“怎么做”留给子类——核心是编译期约束 + 流程控制,不是靠继承自动干活。
用 abstract 方法划出不可绕过的底线
在抽象类里声明没有方法体的方法,比如:
- protected abstract void doPayment(); —— 子类必须实现这个动作,否则编译失败
- 访问修饰符只能是 public 或 protected,不能是 private、static、final
- 返回类型、参数列表、抛出异常都构成契约,子类实现时必须严格匹配(支持协变返回)
- 子类如果是普通类(非 abstract),漏掉任何一个 abstract 方法,编译器直接报错:class Xxx must either be declared abstract or implement abstract method...
用 final 模板方法锁住执行顺序
光有 abstract 方法只能卡住“有没有写”,管不住“什么时候调”。真正起作用的是把主干流程写成 final 方法:
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- public final void execute() { preCheck(); doPayment(); postNotify(); }
- preCheck() 和 postNotify() 是父类提供的普通方法,所有子类复用
- doPayment() 是 abstract 方法,每个子类填自己的支付逻辑,但只能在这个固定位置被调用
- 子类无法重写 execute(),流程骨架不会被破坏
用 protected 字段和构造器统一管理公共状态
抽象类可以持有子类共用的配置或工具,避免重复初始化:
立即学习“Java免费学习笔记(深入)”;
- 声明 protected final Logger logger;、protected final int timeoutMs;
- 在抽象类构造器中校验参数、赋值字段、创建依赖(如 logger = LoggerFactory.getLogger(getClass());)
- 子类构造器只需调用 super(name, timeout),不用再写校验和初始化
- 字段用 protected final,既可被子类直接使用,又防误改
预留钩子和工具方法提升复用性
不是所有逻辑都要强制实现,有些是可选增强:
- 提供 protected void onPaymentSuccess(PaymentResult result) { } 这样的空方法,子类按需重写
- 封装通用能力,如 protected final String generateTraceId() { ... },子类直接调用
- 定义分类异常(BusinessException、SystemException),子类只管 throw,模板统一处理
- 避免把能复用的逻辑也设为 abstract,否则子类被迫写一堆 return null,反而降低可读性

















