抽象类通过final模板方法固定流程骨架,将可变步骤声明为abstract方法由子类实现,辅以钩子方法控制可选分支;包含具体方法、抽象方法和钩子方法三类成员。

抽象类编写模板方法,关键在于用 final 模板方法 固定流程骨架,把可变步骤声明为 abstract 方法,让子类去实现。父类只管“怎么做顺序”,子类负责“每步具体怎么干”。
定义抽象模板类:声明骨架与抽象步骤
抽象类本身不能被实例化,但它能封装通用逻辑,并强制子类遵循统一执行顺序。模板方法必须用 final 修饰,防止子类意外覆盖整个流程。
- 用
public final void templateMethod()定义算法骨架(例如process()、prepareBeverage()) - 在该方法内部按序调用若干步骤:有的已实现(如
boilWater()),有的是protected abstract(如brew()、addCondiments()) - 可选添加钩子方法(
protected boolean hook()),返回布尔值控制是否执行某分支步骤
区分三类方法:哪些写死、哪些留空、哪些可选
一个清晰的抽象模板类通常包含三类成员:
- 具体方法:公共或私有,直接实现通用逻辑(如连接数据库、校验参数、打印日志)
-
抽象方法:用
protected abstract声明,无方法体,子类必须重写(如不同支付方式的签名验签、扣款逻辑) -
钩子方法:有默认实现(如
return true;),子类可选择性@Override修改行为(如是否发送短信通知)
子类只需实现抽象方法,不碰模板结构
子类继承抽象类后,编译器会强制要求实现所有 abstract 方法。它完全不用关心模板方法怎么调用、顺序如何——只要把规定动作填进去就行。
- 例如
Coffee类实现brew()为“冲泡咖啡粉”,Tea类实现为“浸泡茶叶” - 两者调用同一句
beverage.prepareBeverage(),输出却因各自实现而不同 - 如果某个子类不需要某步(比如咖啡不加调料),就重写钩子方法返回
false
典型结构示例(精简版)
以下是一个可直接运行的最小可行结构:
abstract class TaskTemplate {
// 模板方法:流程不可变
public final void execute() {
init();
doCoreWork();
cleanup();
if (needReport()) report();
}
// 具体方法:父类已实现
private void init() { System.out.println("初始化环境"); }
private void cleanup() { System.out.println("释放资源"); }
// 抽象方法:子类必须实现
protected abstract void doCoreWork();
// 钩子方法:子类可覆盖
protected boolean needReport() { return true; }
protected void report() { System.out.println("生成执行报告"); }
}
class FileTask extends TaskTemplate {
@Override protected void doCoreWork() {
System.out.println("读写文件");
}
@Override protected boolean needReport() {
return false; // 不生成报告
}
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











