子类重写父类方法必须签名完全一致(方法名、参数类型、顺序、个数),返回类型协变,访问权限不更严格,且须加@override注解;static、final、private方法不可重写。

子类重写父类方法,核心是让同名方法在子类中有新实现,同时确保运行时能自动调用子类版本——这依赖于签名严格匹配和编译器校验,不是简单改个名字或加个参数就行。
方法签名必须完全一致
重写不是“起个类似的名字”,而是要求方法名、参数类型、参数顺序、参数个数全部与父类方法一模一样。哪怕把 int 换成 Integer,或把 List
- 正确:父类有
void draw(String color),子类也写void draw(String color) - 错误:子类写成
void draw(String... colors)或void draw(Object color)—— 这是重载,不参与多态分派
返回类型要协变或相同
JDK 5 起支持协变返回类型:子类方法可返回父类方法返回类型的子类。比如父类返回 Object,子类可返回 String;但反过来不行——父类返回 String,子类不能返回 Object,否则编译报错 return type is incompatible。
- 允许:
Object getValue()→String getValue() - 禁止:
String getValue()→Object getValue()
访问权限不能更严格
子类方法的修饰符只能比父类更宽松或相等:public ≥ protected ≥ 包级(默认)> private。private 方法根本不可见,谈不上重写;如果父类是 protected,子类就不能用 private 或默认(包级)修饰,否则编译失败。
- 父类
protected void start()→ 子类可用protected或public - 父类
public int getId()→ 子类只能用public
必须加 @Override 注解
这不是可选项,而是强制习惯。它让编译器检查:这个方法是否真能在父类中找到匹配项。漏写可能导致拼错方法名(如 hashcode())、参数写错、或父类方法被删后子类未同步——这些都悄无声息地变成独立方法,多态完全失效。
- 写了
@Override却编译不过?说明不是重写,得回头核对父类方法签名 - IDE 重命名父类方法时,带
@Override的子类方法会自动同步,减少出错
避开常见陷阱
以下情况看似像重写,实则无效:
- static 方法:子类同名 static 方法只是“隐藏”,调用看引用类型,不走动态绑定
- final 方法:编译直接报错,不允许覆盖
- private 方法:子类根本看不到,定义同名方法只是新增,和父类无关
-
异常声明太宽:父类抛
IOException,子类只能抛其子类(如FileNotFoundException)或不抛,不能抛Exception
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











