super用于子类重写方法中显式调用父类原方法,调用时机(前、中、后)依业务逻辑决定:前置适用于预处理,后置适用于收尾,中置适用于加工返回值;仅限非静态、非私有、可访问的重写方法内使用。

核心解法是用 super 在子类重写方法内部显式调用父类原方法,调用时机(前、中、后)由业务逻辑决定。
明确 super 调用的定位与作用
super 不是“恢复”或“绕过”重写,而是主动委托:它让子类在自己的方法体中,精准插入父类原始逻辑的执行点。这依赖继承链的静态结构,不破坏多态,也不改变方法签名。
- super.methodName() 只能在非静态、非私有、可访问的重写方法内使用
- 不能在 static 方法或构造器中调用(除非是 super() 调用父类构造器)
- 调用位置直接影响执行顺序——前置适合预处理,后置适合收尾,中置适合包裹
按业务场景选择调用时机
不是固定“先 super 再扩展”,而是看逻辑依赖关系:
- 需要父类初始化后再增强(如日志记录、权限校验后执行主逻辑)→ 把 super 放在前面
- 需要主逻辑完成再清理或上报(如数据库操作后刷新缓存)→ 把 super 放在中间或后面
- 需要对父类返回值加工(如修改 JSON 响应体)→ super 放中间,用变量承接其返回值
避免常见陷阱
看似简单,但容易因理解偏差导致运行时异常或逻辑错乱:
- 不要在父类构造器里调用可能被子类重写的方法——子类字段尚未初始化,易 NPE
- @Override 方法必须保持签名一致(含返回类型协变)、异常声明不扩大、访问权限不收紧
- 若父类方法是 final 或 private,无法重写,更无法用 super 调用——此时应考虑组合或模板方法模式
替代思路:当 super 不适用时
某些设计下硬套 super 会破坏职责或引发循环调用,可转向更清晰的结构:
- 将父类核心逻辑抽为 protected 模板方法(如 doExecute()),原 public 方法负责通用流程;子类只重写 doExecute()
- 用组合代替继承:子类持有一个父类实例,在需要处委托调用,控制权更明确
- 引入钩子方法(hook method):父类定义空的 before/after 方法,子类选择性重写,无需 super 显式干预

















