方法重写是子类提供父类已定义方法的新实现,要求方法名、参数列表和返回类型一致,访问权限不更严格,是实现多态的关键机制。

方法重写(Override)是指子类提供父类中已定义方法的**新实现**,要求方法名、参数列表和返回类型完全一致,且访问权限不能更严格。它发生在继承关系中,是实现多态的关键机制。
重写的基本条件
要正确重写一个方法,必须同时满足以下几点:
- 子类与父类之间存在继承关系(用 extends)
- 子类中的方法名、参数个数和类型、返回类型(或其子类型)必须与父类方法完全一致
- 子类方法的访问修饰符不能比父类更严格(例如父类是 protected,子类不能用 private)
- 父类方法不能是 final、static 或 private(这些无法被重写)
@Override 注解的作用
在子类方法上添加 @Override 注解不是必须的,但强烈推荐。它有两个实际好处:
- 让编译器检查是否真的重写了父类方法——如果签名写错(比如参数少一个),会直接报错
- 提高代码可读性,明确表达“此处有意替换父类行为”
示例:
class Animal {void sound() { System.out.println("Some sound"); }
}
class Dog extends Animal {
@Override
void sound() { System.out.println("Woof!"); }
}
常见易错点
初学者常因细节疏忽导致“看似重写,实为重载或新方法”:
- 返回类型不兼容:父类返回 Object,子类返回 String 可以(协变返回),但返回 int 就不行(基本类型不支持协变)
- 异常声明更宽泛:子类重写方法不能抛出比父类方法更多或更广的检查型异常(如父类没声明异常,子类不能加 throws IOException)
- 静态方法不能被重写:子类定义同名静态方法,只是隐藏(Hiding),不是重写;调用取决于引用类型,而非实际对象类型
重写 vs 重载 vs 隐藏
三者容易混淆,关键区别在于发生位置和目的:
- 重写(Override):发生在父子类之间,运行时决定调用哪个版本(动态绑定)
- 重载(Overload):发生在同一个类中,参数列表不同,编译时决定(静态绑定)
- 隐藏(Hiding):子类用 static 方法覆盖父类同名 static 方法,或用变量名遮蔽父类变量,也是编译时决定










