重写方法的访问权限不能比父类更严格,异常声明不能扩大受检范围,static/final/private方法不可重写,返回类型须协变或一致。

重写方法的访问权限不能比父类更严格
子类重写方法时,public 可以重写 protected 或 public,但 protected 不能重写 public 方法。Java 要求重写后的方法对外暴露能力不能收缩,否则多态调用可能失败。
-
public方法在父类中 → 子类重写只能是public(protected或private会编译报错) -
protected方法在父类中 → 子类可用protected或public,但不能用private -
default(包私有)方法在父类中 → 子类重写必须同为default或升级为public/protected,不能降级
常见错误现象:Cannot reduce the visibility of the inherited method —— 就是访问权限写窄了。
@Override 标注下抛出异常的限制
重写方法声明的异常范围不能超过父类方法。子类方法可以不抛异常,也可以只抛父类方法中声明的**运行时异常(RuntimeException 及其子类)或其子集**,但不能新增受检异常(checked exception),也不能扩大受检异常范围。
- 父类方法声明
throws IOException→ 子类可throws FileNotFoundException(它是IOException子类),但不能throws Exception或throws SQLException - 父类方法没写
throws→ 子类重写方法也**不能声明任何受检异常**;写throws RuntimeException没问题,因为它是非受检的 - 违反时编译直接报错:
Exception is not compatible with throws clause in ...
本质是里氏替换原则的体现:父类能被安全调用的地方,子类替换后也得能安全调用,不能突然多出要处理的异常。
立即学习“Java免费学习笔记(深入)”;
static、final、private 方法无法被重写
这三个修饰符从语言机制上就排除了动态绑定的可能,所以加 @Override 会直接编译失败。
-
static方法属于类,不是实例行为,子类“同名同签名”的static方法只是隐藏(hiding),不是重写 -
final方法禁止被继承修改,加@Override会报错:Method does not override method from its superclass -
private方法对子类不可见,子类里写的只是个新方法,加@Override同样触发编译错误
注意:IDE 有时会自动补全 @Override,但如果你看到它标红或编译不过,先检查这三类修饰符,别急着删注解——可能是你误以为它能被重写。
返回类型必须协变(covariant)或完全一致
Java 5 开始支持协变返回类型:子类重写方法的返回类型可以是父类方法返回类型的**子类型**,但不能是无关类型或父类型。
- 父类方法返回
Object→ 子类可返回String、List等任意子类 - 父类返回
Number→ 子类可返回Integer、Double,但不能返回Object或String - 基本类型和 void 不参与协变,必须严格一致:父类返回
int,子类不能返回long
这个限制常被忽略,尤其在泛型擦除后容易误判类型关系。如果编译报 return type is incompatible,优先核对返回类型的继承链是否成立。
最麻烦的是组合场景:比如同时改了访问权限 + 异常 + 返回类型,其中一个错了,编译器提示可能不直观。建议每次只动一个点,验证通过再继续。







