抽象类应固化稳定通用逻辑,仅将变化点抽象为abstract方法;用final模板方法确保流程顺序,普通方法封装可复用逻辑,钩子方法提供可选扩展点,避免过度抽象。

抽象类定义公共业务逻辑,关键是把重复、稳定、通用的部分写死在父类里,只把变化点留给子类去实现。
用 final 方法固化核心流程
模板方法模式是典型做法:把整个业务流程串起来,关键步骤用 final 修饰,防止子类篡改顺序或跳过环节。比如订单处理中,校验、执行、通知三步是固定顺序,只有“执行”这一步因业务而异。
- public final void process() { validate(); executeCore(); notifySuccess(); }
- validate() 和 notifySuccess() 是普通私有或受保护方法,直接提供实现
- executeCore() 声明为 protected abstract,强制子类补全
把可复用逻辑抽成普通方法
不带 abstract 的方法就是公共逻辑的载体。它们可以是 private(仅供模板方法调用),也可以是 protected(允许子类调用或扩展),但不要设为 public——否则容易被外部误用,破坏封装。
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 比如统一的日志记录、参数预处理、结果包装等,都适合放在抽象类里作为普通方法
- 避免在这些方法里调用子类可能重写的方法(尤其是构造器中),防止初始化时出现未预期行为
用钩子方法预留轻量扩展点
有些环节不一定每个子类都要干预,但需要保留入口。这时用 protected 的空实现方法,即所谓“钩子”。子类按需重写,不重写也不影响主流程。
- protected void beforeSubmit() { } // 默认什么都不做
- protected void afterPersist() { } // 子类可选择性增强
- 这类方法不加 abstract,不强制实现,但命名和语义要清晰,让继承者一眼明白用途
避免把所有方法都抽象化
常见误区是把本该复用的逻辑也声明为 abstract,导致每个子类都得写一遍几乎相同的代码,反而削弱了抽象类的价值。
- 只对真正“因业务而异”的行为抽象,比如 discount 策略、支付渠道适配、数据源选择
- 像时间戳生成、ID 构建、异常分类这类通用能力,应直接在抽象类中提供默认实现
- 抽象方法越少,骨架越清晰;子类越轻松,维护成本越低
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










