子类重写父类方法需满足:存在继承关系,方法签名一致(含协变返回类型),访问权限不更严格,异常声明不扩大;static、final、private方法不可重写。

Java中方法重写(Override)发生的条件,核心是子类对父类中可访问的非静态、非final方法提供新的实现。只有同时满足以下几个条件,才构成合法的重写:
1. 必须存在继承关系
重写只发生在父子类之间。子类通过 extends 继承父类后,才有机会重写父类的方法。
- 接口实现(implements)不算继承,但实现接口中的抽象方法属于“实现”,不是重写(除非该接口方法有默认实现,此时子类覆盖默认方法才属于重写)
- 同一类中的同名方法只是重载(Overload),不是重写
2. 方法签名必须完全一致
包括:方法名、参数列表(类型、个数、顺序)必须相同;返回类型需满足协变规则(见下条);修饰符不能更严格(如父类是 protected,子类不能改成 private)。
- 参数类型不能自动转型后“看起来一样”——比如父类是 void test(int x),子类写 void test(Integer x) 是重载,不是重写
- 泛型擦除后签名相同也不算重写(如 void show(List
) 和 void show(List) 擦除后都是 show(List),但编译不通过,属重复声明)
3. 返回类型可以是协变的(JDK 5+)
子类重写方法的返回类型,可以是父类方法返回类型的子类型(即更具体的类型),这叫协变返回类型。
立即学习“Java免费学习笔记(深入)”;
- 例如:父类方法返回 Object,子类可重写为返回 String 或 ArrayList
- 基本类型和 void 不支持协变(必须完全相同)
4. 访问权限不能更严格,异常声明不能抛出新或更宽泛的检查异常
这是为了保障里氏替换原则(LSP):子类对象能安全替代父类对象。
- 访问修饰符范围:private protected,子类可用 public,但不能用 private)
- 异常方面:子类重写方法可以抛出更少、更具体的检查异常(甚至不抛),但不能新增或扩大检查异常范围(如父类声明 throws IOException,子类不能 throws Exception)
- 运行时异常(RuntimeException 及其子类)不受此限
基本上就这些。抓住“继承 + 同签名 + 可见 + 非静态非final”,再核对访问与异常规则,就能准确判断是否发生重写。











