抽象方法的核心作用是强制子类实现关键逻辑,需用abstract修饰且无方法体,所在类也须为abstract;配合模板方法可固化流程、开放插槽;钩子方法支持可选扩展;注意避免构造器中调用抽象方法引发空指针。

抽象方法的核心作用,是在基类中“留空”一个方法签名,强制所有非抽象的派生子类必须提供具体实现,从而统一业务行为契约,避免关键逻辑遗漏。
用 abstract 修饰方法,让子类无法绕过实现
在基类中声明抽象方法时,不写方法体(连大括号都不加),且该类本身必须用 abstract 修饰。编译器会在编译期强制校验:任何非抽象子类,若未实现该方法,直接报错,无法通过编译。
- 例如:
protected abstract String generateOrderNo();—— 子类不实现就根本编译不过 - 抽象方法不能是 private(子类不可见)、final(禁止重写)或 static(属于类而非实例)
- 推荐使用 public 或 protected,兼顾可调用性与封装性
配合模板方法,锁死主干流程,只开放关键插槽
光有抽象方法只能卡住入口,真正落地需结合模板方法模式:把不变的执行顺序写死在 final 方法中,把可变环节声明为抽象方法,交给子类填空。
- 比如订单处理流程:
validate() → calculateFee() → persist() → sendNotification() - 其中
calculateFee()设为 protected abstract,不同业务类型(普通/团购/跨境)各自实现计费逻辑 - 模板方法内可统一做参数校验、事务控制、日志记录等,子类无需重复劳动
区分“必须实现”和“按需扩展”,用钩子方法增强灵活性
除强制实现的抽象方法外,基类还可定义空的 protected 方法作为钩子,子类可选择性重写,不破坏契约又保留扩展空间。
- 例如:
protected void onPaymentSuccess(Order order) { } - 风控子类重写它追加审计日志,普通子类保持默认空实现即可
- 命名建议带
onXXX或afterXXX前缀,语义清晰,便于识别
注意继承链中的责任传递与初始化安全
抽象方法的约束可逐层向下传递:抽象子类可不实现父类抽象方法,但最终必须由某个具体子类完整履行;同时要避免在父类构造器中调用抽象方法,否则子类字段尚未初始化,易引发空指针。
- 若子类是 abstract,可延迟实现,作为中间抽象层(如
Mammal extends Animal) - 若子类是具体类(非 abstract),则必须实现基类及其所有祖先类中所有未实现的抽象方法
- 不要在抽象类构造器里调用抽象方法——这是常见却隐蔽的运行时风险点











