【Java】一文吃透方法重写与重载:核心原理+代码实战
大家好,我是云扬~ 今天咱们来聊聊 Java 中两个容易混淆但至关重要的概念:方法重写(Override) 和 方法重载(Overload)。这俩是 Java 面向对象编程的基础,也是面试高频考点,掌握它们不仅能提升代码可读性,更是实现多态的关键。话不多说,直接上干货!
一、为什么需要重载和重写?
在实际开发中,我们经常会遇到这样的场景:
- 想实现 “加法” 功能,但可能需要加两个 int、三个 int,或者加两个 double—— 如果每个功能都起不同名字(比如 add2Int、add3Int、add2Double),代码会变得臃肿难记;
- 子类继承父类后,父类的方法逻辑满足不了子类需求(比如父类的 “计算面积” 方法只适用于矩形,子类圆形需要专属实现),但又想沿用方法名方便调用。
这时候,重载和重写就派上用场了 —— 它们让相同方法名适配不同场景,既提升了代码复用性,又增强了可读性。
二、方法重载(Overload):同一类中的 “多面手”
1. 定义
在同一个类中,存在多个方法名相同但参数不同的方法,这就是重载。注意:返回值类型、访问修饰符不影响重载判断,核心是 “参数不同”。
2. 实现方式(附代码示例)
重载的核心是 “改变参数”,具体有三种形式:
public class Calculator {
// 1. 改变参数个数
public int add(int a, int b) {
return a + b;
}
public int add(int a, int b, int c) {
return a + b + c;
}
// 2. 改变参数类型
public double add(double a, double b) {
return a + b;
}
// 3. 改变参数顺序(需不同类型,否则无意义)
public String add(String name, int age) {
return "姓名:" + name + ",年龄:" + age;
}
public String add(int age, String name) {
return "年龄:" + age + ",姓名:" + name;
}
// 注意:返回值不同不构成重载(编译报错)
// public double add(int a, int b) { return a + b; }
}
3. 关键注意点
- 重载 main 方法:可以重载,但程序入口只能是
public static void main(String[] args):
public class OverloadMain {
public static void main(String[] args) {
System.out.println("程序入口");
main(123); // 调用重载的main方法
}
public static void main(int num) {
System.out.println("重载的main方法:" + num);
}
}
- 隐式类型转换:当传入参数没有完全匹配的方法时,会触发向上转型(byte→short→int→long→float→double):
public class TypeConvert {
public static void print(int num) {
System.out.println("int类型:" + num);
}
public static void main(String[] args) {
byte b = 10;
print(b); // 隐式转为int,输出"int类型:10"
}
}
三、方法重写(Override):子类对父类的 “个性化改造”
1. 定义
子类继承父类后,定义与父类方法名、参数列表、返回值类型完全相同的方法,用于覆盖父类方法的实现,这就是重写。重写是实现多态的核心前提。
2. 重写规则(附代码示例)
重写有严格的规则约束,违反则编译报错,记住 “两同一小一大” 口诀(后面会总结),先看代码:
// 父类
public class Animal {
// 父类方法:protected修饰,抛出IOException
protected void eat() throws IOException {
System.out.println("动物吃东西");
}
// final方法:不能被重写
public final void sleep() {
System.out.println("动物睡觉");
}
// static方法:不能被重写(子类可定义同名静态方法,但属于隐藏,非重写)
public static void run() {
System.out.println("动物奔跑");
}
}
// 子类
public class Dog extends Animal {
// 重写父类eat方法
@Override // 注解:校验重写规则,推荐添加
public void eat() throws FileNotFoundException { // 权限更宽松(protected→public),异常更小(IOException子类)
super.eat(); // 调用父类被重写的方法
System.out.println("狗吃骨头");
}
// 错误示例1:参数不同,不是重写(实际是重载)
// public void eat(String food) { System.out.println("狗吃" + food); }
// 错误示例2:权限更严格(protected->private),编译报错
// private void eat() { System.out.println("狗吃骨头"); }
// 错误示例3:抛出更高级异常,编译报错
// public void eat() throws Exception { System.out.println("狗吃骨头"); }
// 静态方法:同名但非重写(隐藏父类方法)
public static void run() {
System.out.println("狗跑");
}
}
3. 核心规则详解
- 前提条件:必须存在继承关系(is-a),子类只能重写父类的非 private 方法(private 方法子类不可见)。
- “两同”:方法名相同、参数列表完全相同(顺序、类型、个数一致)。
- “一小”:子类方法抛出的异常类型 ≤ 父类方法(仅针对 checked 异常,运行时异常无限制)。
- “一大”:子类方法访问权限 ≥ 父类方法(public > protected > default > private)。
- 禁止重写的情况:final 方法(不可继承)、static 方法(属于类级别的方法,无对象多态)、构造方法(子类构造方法与父类类名不同,无法重写)。
- 特殊说明:synchronized、strictfp 关键字不影响重写规则(前者控制多线程同步,后者控制浮点精度,与重写逻辑无关)。
四、重载与重写核心区别(表格总结)
| 对比维度 | 方法重载(Overload) | 方法重写(Override) |
|---|---|---|
| 存在范围 | 同一个类中 | 子类与父类之间 |
| 方法名 | 相同 | 相同 |
| 参数列表 | 必须不同 | 必须相同 |
| 返回值类型 | 无要求(可相同可不同) | 必须相同(或子类类型,Java 5 + 支持) |
| 访问权限 | 无要求 | 子类 ≥ 父类 |
| 异常处理 | 无要求 | 子类 ≤ 父类(checked 异常) |
| 核心目的 | 适配不同参数场景,提升可读性 | 覆盖父类逻辑,实现多态 |
| 关键字 | 无 | @Override(推荐使用,校验规则) |
五、口诀记忆法
- 重载:两同一不同(同一类、同方法名,参数不同);
- 重写:两同一小一大(同方法名、同参数,异常更小、权限更大)。
写在最后
方法重载和重写是 Java 基础中的基础,理解它们的核心区别和使用场景,能让你的代码更规范、更灵活。记住:重载解决 “同一类中同名方法适配不同参数” 的问题,重写解决 “子类个性化实现父类方法” 的问题。
如果觉得本文对你有帮助,欢迎点赞、留言交流~ 后续还会分享更多 Java 核心知识点,关注云扬の Blog,一起在技术路上稳步前行!



