子类重写父类方法必须遵守四条强制规则:方法签名完全一致;返回值基本类型和void须相同、引用类型支持协变;访问权限不能更严格;checked异常声明不能更宽泛。

子类重写父类方法时,必须严格遵守的四条核心规则,是保障多态正确性与编译通过的基础。它们不是建议,而是Java语言强制执行的语法规则。
方法签名必须完全一致
方法签名 = 方法名 + 参数列表(参数类型、个数、顺序)。三者缺一不可,必须与父类被重写方法逐字节相同。
- 仅改返回值、异常或访问修饰符 → 不算重写,编译器不识别为Override
- 参数类型从 int 改成 Integer → 属于重载,不是重写(自动装箱不改变签名)
- 方法名拼错(如 toString 写成 toSting)→ 编译通过但无实际重写效果
返回值类型必须兼容
基本类型和 void 必须完全相同;引用类型允许“协变返回”,即子类可返回父类返回类型的子类。
- 父类返回 Animal,子类可返回 Dog(Dog extends Animal)✅
- 父类返回 int,子类返回 long ❌(编译报错)
- 父类返回 String,子类返回 Object ❌(扩大范围不被允许)
访问权限不能更严格
子类方法的访问修饰符,必须等于或宽于父类方法。权限由宽到严:public > protected > default(包私有) > private。
- 父类是 protected → 子类可用 protected 或 public ✅
- 父类是 public → 子类不能用 protected 或 private ❌
- 父类是 private → 子类根本无法继承,所谓“重写”不成立,只是定义了同名新方法
异常声明不能更宽泛
仅针对 checked 异常(编译时异常)。子类方法抛出的 checked 异常,只能是父类声明异常的子类,或不抛,或抛更少。
- 父类声明 throws IOException → 子类可 throws FileNotFoundException(它是 IOException 子类)✅
- 父类声明 throws IOException → 子类写 throws Exception ❌(范围更宽)
- 父类无异常声明 → 子类只能抛 RuntimeException 及其子类,不可抛 SQLException 等 checked 异常
这四条规则共同构成 Override 的刚性边界。实践中务必配合 @Override 注解使用——它不是装饰,而是编译器帮你实时校验是否真正满足全部四条规则的“安全锁”。漏掉任一条,要么编译失败,要么行为不符合预期。











