重写方法必须满足:方法名、参数列表(类型、顺序、数量)完全一致,返回类型协变(相同或子类型),且不能重写static、final、private方法;@Override注解用于编译期强制校验。

重写方法必须满足哪些签名条件
Java 中重写 override 不是简单地“名字一样就行”,编译器会严格校验:子类方法名、参数列表(类型和顺序)、返回类型(或其协变子类型)必须与父类被重写方法完全一致。如果只改了返回类型为不兼容类型(比如父类返回 Object,子类返回 String),会报编译错误 error: return type is incompatible;如果参数类型不同(比如父类是 int,子类写成 Integer),那不是重写,而是重载(overload),多态不会触发。
- 必须用
@Override注解——它不是可选的装饰,而是编译器检查重写的强制开关,漏写会导致意外继承旧逻辑 - 访问修饰符不能比父类更严格(
protected父类方法,子类不能改成private),但可以更宽松(protected→public) - 父类方法如果是
final或static,根本无法重写,编译直接报错
为什么调用时有时没走子类重写的方法
常见原因是用父类类型声明变量,但实际指向子类对象时,仍没触发重写逻辑——这通常不是多态失效,而是调用方式错了。例如:Parent p = new Child(); p.method(); 是正常多态;但如果写成 new Parent().method() 或误用了静态方法,就永远进不了子类。
- 确认调用对象是子类实例,而非父类实例(可用
obj.getClass()打印验证) - 检查是否误在子类中定义了同名但参数不同的方法(即重载),导致你以为重写了,其实只是新增了一个方法
- 避免在构造函数中调用将被重写的方法——此时子类字段可能还未初始化,容易引发
NullPointerException或未定义行为
重写 toString / equals / hashCode 有哪些坑
这三个方法是重写高频区,但也是出问题最多的地方。尤其是 equals,JDK 规范要求必须满足自反性、对称性、传递性、一致性,且对 null 安全。很多手写 equals 只比较字段,却忘了先判 instanceof 或用 Objects.equals(),结果遇到子类传入就返回 false,破坏多态语义。
-
toString()重写后建议包含类名和关键字段,避免调试时全是ClassName@1a2b3c -
hashCode()必须与equals保持一致:若两个对象equals()返回true,它们的hashCode()必须相同 - IDE 自动生成的
equals/hashCode默认只考虑本类字段,若子类也参与等价判断,需在子类中显式重写并调用super.equals()
接口 default 方法能否被重写
可以,而且规则和抽象类方法重写基本一致:子类(或实现类)可以用 @Override 提供新实现。但要注意,如果一个类同时继承父类并实现接口,且两者都有同签名的 default 方法和非 private 实例方法,Java 要求你必须显式重写该方法,否则编译失败(“diamond problem” 的显式解决)。
立即学习“Java免费学习笔记(深入)”;
- 接口
default方法不能被static方法重写(语法不允许) - 重写接口
default方法时,不能降低可见性(如从public改成protected) - 若父类已有同签名方法,子类重写的是父类版本,接口
default自动被忽略——这点容易被忽略,导致预期调用接口逻辑却走了父类


















