子类重写父类逻辑需明确意图(完全替换、补充增强或条件调整),严格遵守接口契约,善用super()复用,加@Override注解防错。

子类重写父类逻辑不是“换掉代码”,而是有策略地在继承基础上表达特异性——关键在于意图清晰、契约守牢、复用得当。
先明确重写的真正意图
动笔前问自己:是要完全替换、补充增强,还是条件性调整?不同意图对应不同写法,选错会引发逻辑断裂或功能丢失。
-
完全替换:父类逻辑不适用,子类独立实现。例如
Dog.speak()输出“汪汪”,与Animal.speak()的通用叫声无关联 -
补充增强:父类完成基础校验或初始化,子类在其后追加专属动作。例如用户创建后,
VipUser额外发送权益短信 -
条件调整:主干流程沿用父类,仅在关键节点插入子类判断。例如支付成功后,仅
CorporateAccount触发对账,普通账户跳过
严格守住接口契约
方法名、参数类型(含泛型擦除后原始类型)、个数和顺序必须完全一致;返回类型可协变(如父类返回 Response,子类可返回 SuccessResponse),但不可随意变更。
- ❌ 错误示例:
void save(List<Order>)→ 子类写成void save(ArrayList<Order>),实际是重载,多态调用进不去 - ✅ 正确做法:保持签名一致;内部需强类型操作时,用
instanceof判断或安全转型 - 若需新增能力,优先封装新方法,而非扭曲原方法语义
善用 super() 复用父类逻辑
super() 不是技巧,而是维持继承链健壮性的核心机制。它按 MRO 自动定位下一个类,避免硬编码父类名带来的耦合风险。
立即学习“Java免费学习笔记(深入)”;
- 构造器中务必写
super().__init__(),否则字段可能未初始化 - 普通方法中用
super().method()复用校验、日志、清理等通用逻辑 - 可灵活组合:前置预处理(如权限校验)、中间介入(根据父类返回值分支)、后置追加(如资源关闭、通知发送)
加 @Override 注解,把错误挡在编译期
这个注解本身不改变行为,但它是防错开关和自文档工具。不加也能运行,但一旦方法名拼错、参数微调或父类方法被删,你将毫无察觉——以为重写了,其实只是新增了一个同名方法。
- 加了注解后报错 “does not override”?立刻检查:是否 private/static/final?参数类型是否真一致?父类方法是否存在?
- IDE 自动生成重写方法时,注意泛型类型参数(如
<T extends User> T process(T input))不能遗漏 - 接口的默认方法也可用
@Override重写,语义不同但校验逻辑一致
不复杂但容易忽略


















