Java 重写与重载
Override(重写)与 Overload(重载)名字相似但完全是两回事:重写发生在父子类之间、方法签名必须相同;重载发生在本类中、方法名相同但参数必须不同。
重写 Override
子类继承父类后,可以对父类方法不满意的方法重新实现:定义方法签名完全相同的方法即为重写。调用时实际执行子类版本。
class Animal {
void speak() {
System.out.println("动物叫");
}
}
class Dog extends Animal {
@Override
void speak() { // 重写父类 speak
System.out.println("汪汪");
}
}
public class OverrideDemo {
public static void main(String[] args) {
Animal a = new Dog(); // 父类引用指向子类对象
a.speak(); // 输出:汪汪(调用子类重写版本)
}
}
@Override 注解
重写方法建议加上 @Override 注解。它不是必需的,但编译器会帮你检查:如果签名写错(方法名拼错、参数类型不同),编译直接报错,防止“本想重写却意外变成新方法”。
重写规则
- 方法名与参数列表必须和父类方法相同。
- 返回类型可以相同,也可以是父类返回类型的子类型(协变返回)。
- 访问权限不能比父类更小:父类是 public,子类不能写成 private。
- 抛出的检查异常不能比父类更宽(父类不抛,子类也不能抛)。
- static、private、final 方法不能被重写。
重载 Overload
同一类中定义多个同名方法,参数列表不同(个数、类型或顺序),调用时编译器按实参选择最匹配的一个。返回类型可不同,但不能只靠返回类型区分重载:
public class CalcDemo {
static int add(int a, int b) {
return a + b;
}
static int add(int a, int b, int c) { // 参数个数不同
return a + b + c;
}
static double add(double a, double b) { // 参数类型不同
return a + b;
}
public static void main(String[] args) {
System.out.println(add(1, 2)); // 输出:3
System.out.println(add(1, 2, 3)); // 输出:6
System.out.println(add(1.5, 2.5)); // 输出:4.0
}
}
重写与重载区别表
| 对比项 | 重写 Override | 重载 Overload |
|---|---|---|
| 发生位置 | 子类与父类之间 | 同一个类中 |
| 方法名 | 必须相同 | 必须相同 |
| 参数列表 | 必须相同 | 必须不同 |
| 返回类型 | 相同或协变 | 随意(不能仅靠它区分) |
| 关键字 | @Override 注解 | 无 |
| 绑定时机 | 运行时(动态绑定) | 编译时确定 |
super 调用父类方法
子类重写后仍想用父类的原实现,用 super.方法名():
class Husky extends Dog {
@Override
void speak() {
super.speak(); // 先执行父类 Dog 的版本
System.out.println("哈士奇嚎叫");
}
}
// 片段需放进 main 方法中运行:
// new Husky().speak(); 输出:汪汪、哈士奇嚎叫
小结:重写是子类按相同签名替换父类实现(运行时多态的基础),重载是同名方法靠参数列表区分;重写要遵守权限、返回类型、异常等规则,必要时用 super 调父类实现。