子类重写父类方法时访问权限只能扩大或保持不变,这是java编译器强制规则,旨在保障多态安全与里氏替换原则;若缩小权限(如父类public子类protected),编译期直接报错“cannot reduce the visibility”。

子类重写父类方法时,访问权限只能扩大或保持不变,不能缩小——这不是设计偏好,而是 Java 编译器强制执行的硬性规则,根源在于保障多态调用的安全性和里氏替换原则。
为什么不能缩小?多态调用会直接崩溃
Java 允许用父类类型引用指向子类对象,例如:
Animal a = new Dog();
a.sound();
编译器只认 Animal 类中 sound() 的声明权限。如果父类是 public,而子类重写为 protected,外部代码通过 Animal 引用调用就会在编译期报错:
Cannot reduce the visibility
不是运行时报异常,是根本编译不过。
各类父类权限对应的子类合法选择
子类重写时必须满足“下限不可破”:
- 父类是 public → 子类必须用 public(改 protected 或 default 直接报错)
- 父类是 protected → 子类可用 protected 或 public(不能降为 default 或 private)
- 父类是 default(包私有)→ 子类仅限同包内重写,且只能是 default、protected 或 public
- 父类是 private → 不参与继承,子类中同名方法只是独立定义,不算重写
权限扩大是安全的增强,不是越界
放宽权限不会破坏原有契约,反而扩展使用场景:
- 父类 protected void save(),子类重写为 public void save()
- 原来能通过父类引用调用的地方依然能调
- 包外代码还能通过子类引用直接调用,能力边界变宽,但不违反里氏替换
接口实现和抽象方法也遵循同一规则
接口中方法默认是 public abstract,所以实现类必须显式写 public;
抽象类中的抽象方法若声明为 public,子类实现时也必须是 public。
哪怕父类或接口没写 public,你也不能省略——不加或写成 protected/default 都会编译失败。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











