Java中的方法重载和覆盖是面向对象编程里两个核心的方法使用特性,二者都能让同一个方法名对应不同的执行逻辑,但实现的场景和规则存在明显差异,接下来分别介绍具体的实现方式。

方法重载的实现
方法重载指的是在同一个类中,定义多个方法名相同但参数列表不同的方法,返回值类型可以相同也可以不同,访问修饰符也没有限制,核心要求是参数列表存在差异,常见的差异包括参数个数不同、参数类型不同、参数顺序不同。
以下是一个方法重载的示例代码:
public class OverloadDemo {
// 无参的add方法
public int add() {
return 0;
}
// 两个int参数的add方法
public int add(int a, int b) {
return a + b;
}
// 三个int参数的add方法,参数个数不同
public int add(int a, int b, int c) {
return a + b + c;
}
// 两个double参数的add方法,参数类型不同
public double add(double a, double b) {
return a + b;
}
// int和double参数的add方法,参数顺序不同
public double add(int a, double b) {
return a + b;
}
// double和int参数的add方法,参数顺序不同
public double add(double a, int b) {
return a + b;
}
public static void main(String[] args) {
OverloadDemo demo = new OverloadDemo();
System.out.println(demo.add()); // 输出0
System.out.println(demo.add(1, 2)); // 输出3
System.out.println(demo.add(1, 2, 3)); // 输出6
System.out.println(demo.add(1.5, 2.5)); // 输出4.0
System.out.println(demo.add(1, 2.5)); // 输出3.5
System.out.println(demo.add(1.5, 2)); // 输出3.5
}
}方法重载的注意事项
- 重载只和参数列表有关,和返回值类型、访问修饰符无关,如果仅返回值不同参数列表相同,不属于重载,会编译报错。
- 参数顺序不同仅在参数类型不同的情况下才构成重载,比如两个参数都是int类型,仅顺序交换不算重载。
- 重载是编译时多态,程序在编译阶段就会根据传入的参数确定调用哪个方法。
方法覆盖的实现
方法覆盖也叫方法重写,指的是子类继承父类之后,对父类中允许访问的方法的实现逻辑进行重新编写,要求子类方法的名称、参数列表、返回值类型和父类方法完全一致,且访问修饰符不能比父类的更严格,同时不能抛出比父类方法更多的 checked 异常。
以下是一个方法覆盖的示例代码:
// 父类
class Parent {
// 父类的show方法
public void show(String content) {
System.out.println("父类输出内容:" + content);
}
// 父类返回String类型的方法
public String getInfo() {
return "父类的info";
}
}
// 子类继承父类
class Child extends Parent {
// 覆盖父类的show方法,参数列表、返回值类型和父类一致
@Override
public void show(String content) {
System.out.println("子类输出内容:" + content);
}
// 覆盖父类的getInfo方法,返回值类型一致
@Override
public String getInfo() {
return "子类的info";
}
public static void main(String[] args) {
Parent parent = new Parent();
parent.show("测试"); // 输出:父类输出内容:测试
System.out.println(parent.getInfo()); // 输出:父类的info
Child child = new Child();
child.show("测试"); // 输出:子类输出内容:测试
System.out.println(child.getInfo()); // 输出:子类的info
// 父类引用指向子类对象,调用的是子类覆盖后的方法
Parent poly = new Child();
poly.show("测试"); // 输出:子类输出内容:测试
System.out.println(poly.getInfo()); // 输出:子类的info
}
}方法覆盖的注意事项
- 父类中使用
private修饰的方法无法被子类覆盖,因为子类无法访问父类的私有方法。 - 父类中使用
final修饰的方法无法被子类覆盖,final方法不允许被重写。 - 子类覆盖方法时,访问修饰符必须大于等于父类的访问修饰符,比如父类方法是
protected,子类方法可以是protected或者public,不能是private。 - 覆盖是运行时多态,程序在运行阶段会根据对象的实际类型确定调用哪个方法。
- 可以使用
@Override注解来标记覆盖的方法,编译器会检查是否符合覆盖的规则,不符合会直接报错。
重载和覆盖的核心区别
| 对比维度 | 方法重载 | 方法覆盖 |
|---|---|---|
| 发生范围 | 同一个类中 | 子类与父类之间 |
| 要求 | 方法名相同,参数列表不同 | 方法名、参数列表、返回值类型都相同 |
| 访问修饰符 | 无限制 | 不能比父类更严格 |
| 多态类型 | 编译时多态 | 运行时多态 |
| 关联注解 | 无 | 可使用@Override注解 |