刚学 Java 的时候,你是不是经常听到“这个方法重载了”、“那个方法被重写了”?听起来很像,但其实它们完全是两回事!今天我们就用生活化的例子 + 清晰对比,帮你彻底分清 重载 和 重写!
一、 先看个生活例子:点餐
想象你在一家面馆点“牛肉面”:
- 你说:“来碗牛肉面!” → 店员给你一碗普通牛肉面。
- 你说:“来碗加蛋加辣的牛肉面!” → 店员给你升级版。
- 你说:“来碗不要香菜的牛肉面!” → 店员按你的要求调整。
👉 这就是 同一个“点牛肉面”的动作,根据你给的“参数不同”,做出不同响应 —— 这就是 重载!
再想象你去两家不同的面馆:
- A 面馆的牛肉面:汤浓肉多;
- B 面馆的牛肉面:清汤寡水。
虽然都叫“牛肉面”,但做法完全不同。
👉 这就像子类 重新定义了父类的方法行为 —— 这就是 重写!
二、什么是方法重载
发生在同一个类中,方法名相同,但 参数列表不同(类型、个数、顺序)。
public class Calculator {
// 两个整数相加
public int add(int a, int b) {
return a + b;
}
// 三个整数相加
public int add(int a, int b, int c) {
return a + b + c;
}
// 两个小数相加
public double add(double a, double b) {
return a + b;
}
}
✅ 重载的特点:
- 方法名 必须相同;
- 参数列表 必须不同(返回值类型不同不算重载!);
- 发生在 同一个类 或 父子类之间(但本质还是“同名不同参”);
- 是 编译时多态。
❌ 注意:仅靠返回值不同,不能构成重载!
比如int f()和double f()会报错!
三、什么是方法重写
发生在父子类之间,子类 重新实现 父类的某个方法。
// 父类
class Animal {
public void makeSound() {
System.out.println("动物发出声音");
}
}
// 子类
class Dog extends Animal {
@Override // 建议加上这个注解,防止写错
public void makeSound() {
System.out.println("汪汪汪!");
}
}
✅ 重写的特点:
- 方法名、参数列表、返回类型 必须完全相同(Java 5+ 支持子类返回更具体的类型);
- 访问权限 不能更严格(比如父类是
public,子类不能是private); - 不能重写
private、static、final方法; - 是 运行时多态,通过对象实际类型决定调用哪个方法。
四、一张表看懂核心区别
| 特性 | 重载 | 重写 |
|---|---|---|
| 发生位置 | 同一个类(或父子类) | 父子类之间 |
| 方法名 | 相同 | 相同 |
| 参数列表 | 必须不同 | 必须相同 |
| 返回类型 | 可同可不同(不影响重载) | 必须相同(或子更具体) |
| 多态类型 | 编译时多态 | 运行时多态 |
| 关键字 | 无 | 建议使用 @Override 注解 |
| 是否继承相关 | 否 | 是 |
五、总结口诀
- 重载看参数,重写看继承;
- 重载同名不同参,重写同名又同参;
- 重载编译定,重写运行定!
记住这个口诀,面试再也不怕问!
六、思考题
下方代码输出什么:
class Test {
public void print(String s) { ... }
public void print(Object o) { ... }
public int print(String s) { ... } // ❌ 编译错误!
}
❌ 第三行和第一行只有返回值不同,不是重载,会报错!