Java子类重写父类方法时,访问权限不能收窄、检查型异常不能扩大,协变返回类型仅限引用类型向下兼容,接口实现和抽象方法同样适用——所有规则均强制保障里氏替换原则。

子类重写父类方法时,访问权限不能收窄、异常声明不能扩大——这不是风格建议,而是Java编译器强制拦截的硬性红线。它直接服务于里氏替换原则,确保Animal a = new Dog(); a.makeSound();这类多态调用永远安全、可预期。
访问权限只能持平或放宽,绝不可收紧
父类方法的可见性决定了“谁能在哪调用它”,子类重写后必须维持甚至增强这一能力,否则父类引用指向子类对象时会直接失效。
- 父类是
public→ 子类必须是public(改protected或private会报错:Cannot reduce the visibility) - 父类是
protected→ 子类可用protected或public,但不能用默认(包私有)或private - 父类是默认(无修饰符)→ 子类可用默认、
protected或public,但不能是private - 父类是
private→ 不可重写(子类同名方法只是独立声明,与继承无关)
检查型异常只能缩小或保持,不能扩大
这条规则只约束checked exception(如IOException、SQLException),运行时异常(RuntimeException及其子类)完全不受限。
- 父类没声明 checked 异常 → 子类不能抛
IOException等,但可以抛IllegalArgumentException - 父类声明
IOException→ 子类可抛FileNotFoundException(它是IOException子类),也可不抛,但不可抛Exception(更宽泛)或SQLException(无关类型) - 子类方法可以比父类抛得更少、更具体,但绝不允许更多、更笼统
协变返回类型:仅限引用类型向下兼容
这不是访问或异常规则,但常被误认为“红线松动”——它其实是安全放宽,仅适用于引用类型返回值。
- 父类返回
Animal→ 子类可返回Dog或Cat(子类实例天然可赋值给父类引用) - 父类返回
String→ 子类不能返回Object(扩大范围,编译失败) - 父类返回基本类型(如
int、boolean)或void→ 子类必须严格一致
接口实现和抽象方法同样适用这些规则
接口中所有方法默认public,所以实现类中@Override的方法也必须是public;抽象方法被子类实现时,也不能收窄权限。这些规则统一服务于同一个目标:确保任何符合父类契约的地方,子类都能无缝替代。

















