抽象类通过“写死公共逻辑、留空差异部分”管理子类,封装校验、日志等共用行为为final方法,用final模板方法固化流程(如pay()含checkorder→dopay→recordlog),以abstract方法定义子类必须实现的契约(如render),辅以onbefore/after钩子支持柔性扩展。

抽象类管理子类公共逻辑,核心是“该写的写死,该留的留空”——把所有子类共用的代码放进抽象类里,把真正因业务而异的部分标为 abstract,让子类必须填。
封装可复用的具体行为
校验、日志、参数预处理、资源初始化这类逻辑,只要多个子类都做,就直接在抽象类中实现为 public 或 protected final 方法。子类自动继承,无需重复写。
- 比如订单系统中,“校验订单状态”和“记录操作日志”是通用步骤,写成具体方法供模板调用
- 避免把公共逻辑散落在各个子类里,否则改一处就得同步改多处
- 不建议在抽象类里写带副作用的具体方法(如发 HTTP 请求),除非确认所有子类都需执行
用 final 模板方法锁定主干流程
把不变的执行顺序固化在 public final void 方法中,内部按序调用已实现的公共方法和待子类实现的 abstract 方法。
- 例如:pay() 方法固定为 checkOrder() → doPay() → recordLog(),其中只有 doPay() 是 abstract
- final 修饰确保子类无法绕过或打乱流程,防止定制失控
- 流程骨架一旦稳定,后续新增子类只需专注实现差异点,不碰主干
通过抽象方法划清契约边界
哪些逻辑必须由子类自己决定?把这些点明确定义为 protected abstract 方法,签名要清晰、语义要明确。
- 命名体现行为意图,如 render()、serializeToXml(),而不是 doStep2()
- 参数尽量精简,共用上下文(如配置、上下文对象)应提前设为抽象类字段或通过 protected 方法提供
- 若子类实现中频繁出现 if-else 分支判断类型,说明抽象方法粒度太粗,应拆得更细或改用模板+钩子组合
用钩子方法支持柔性扩展
对“多数子类不需要干预,但个别需要定制”的环节,定义空实现的 protected void onXXX() 钩子方法,模板中调用它。
- 比如模板末尾调用 onAfterPersist(),默认什么也不做
- A 子类重写它加审计日志,B 子类保持默认,互不影响
- 钩子命名推荐用 onBefore/after 或 before/after 前缀,一眼可知时机和用途
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











