Java中方法重写通过保持签名一致、用super调用父类逻辑并扩展前后操作来实现子类行为增强,需满足方法名参数相同、返回类型协变、访问修饰符不更严格等条件,依赖运行时多态。

Java 中通过方法重写(Override)实现子类对父类行为的扩展,核心是让子类在继承父类方法的基础上,修改或增强其逻辑,同时保持方法签名一致。关键在于用 super 调用父类原逻辑,再在其前后添加子类特有操作。
重写必须满足的条件
只有满足以下要求,才算有效重写,否则编译报错或变成重载:
- 方法名、参数列表(个数、类型、顺序)必须与父类完全相同
- 返回类型需相同,或是父类返回类型的子类型(协变返回类型)
- 访问修饰符不能比父类更严格(如父类是
protected,子类不能是private) - 不能重写被
final、static或private修饰的方法 - 建议加上
@Override注解,帮助编译器检查并提升可读性
在父类逻辑基础上做前置/后置扩展
这是最典型的扩展方式:保留父类功能,再补充子类专属处理。比如日志记录、参数校验、结果包装等。
示例:
立即学习“Java免费学习笔记(深入)”;
<font color="#888">class Animal {
void move() {
System.out.println("动物在移动");
}
}
<p>class Dog extends Animal {
@Override
void move() {
System.out.println("狗开始奔跑前摇晃尾巴"); // 前置扩展
super.move(); // 执行父类逻辑
System.out.println("狗停下后吐舌头喘气"); // 后置扩展
}
}</font>调用 new Dog().move() 会输出三行,既复用了父类行为,又注入了子类细节。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
根据子类特性调整部分逻辑分支
当父类方法包含通用流程但某些环节因类型而异时,可在重写中替换特定步骤。常见于模板方法模式的变体。
- 父类用
final封装主干流程,留出抽象/可重写方法供子类定制 - 或直接重写整个方法,在其中用
if-else/ 多态判断做差异化处理(不推荐过度使用,易破坏开闭原则)
更合理的方式是结合 super 和条件逻辑:
<font color="#888">class Calculator {
double calculate(double a, double b) {
return a + b;
}
}
<p>class TaxCalculator extends Calculator {
private final double taxRate = 0.08;</p><pre class='brush:java;toolbar:false;'>@Override
double calculate(double a, double b) {
double base = super.calculate(a, b); // 复用基础运算
return base * (1 + taxRate); // 只扩展税费计算部分
}}
注意运行时多态与重写的绑定时机
重写生效依赖于对象的实际类型(运行时类型),而非引用类型。这意味着:
- 即使变量声明为父类类型,只要指向子类实例,调用的就是子类重写后的方法
- 构造器中调用重写方法要格外小心——此时子类对象尚未初始化完成,可能导致未定义行为
- 静态方法不能被重写(只能被隐藏),字段也不参与多态
例如:Animal a = new Dog(); a.move(); 执行的是 Dog.move(),不是 Animal.move()。

















