重载和重写到底有啥区别?

101 阅读3分钟

刚学 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);
  • 不能重写 privatestaticfinal 方法;
  • 是 运行时多态,通过对象实际类型决定调用哪个方法。

四、一张表看懂核心区别

特性重载重写
发生位置同一个类(或父子类)父子类之间
方法名相同相同
参数列表必须不同必须相同
返回类型可同可不同(不影响重载)必须相同(或子更具体)
多态类型编译时多态运行时多态
关键字建议使用 @Override 注解
是否继承相关

五、总结口诀

  • 重载看参数,重写看继承;
  • 重载同名不同参,重写同名又同参;
  • 重载编译定,重写运行定!

记住这个口诀,面试再也不怕问!

六、思考题

下方代码输出什么:

class Test {
    public void print(String s) { ... }
    public void print(Object o) { ... }
    public int print(String s) { ... } // ❌ 编译错误!
}

❌ 第三行和第一行只有返回值不同,不是重载,会报错!