💡 一则也许对你有用的小广告 🏆

欢迎飞飞程序员   ,你将获得:专属的实战项目(已更新的所有会员标识的项目都能学习) / 1v1 提问 / Java 学习路线 / PHP 学习路线 / 学习打卡 / 社群讨论

  • 正在进行中的项目:《FFBlog知识付费博客项目》 正在持续更新中,基于 Spring Boot 3.x + JDK 21...,点击查看 ;
  • 《从零开发:FFBlog知识付费博客项目(全栈开发)》 演示链接: https://ffblog.ffcxy.com/  ;

截止目前, 飞飞  正在疯狂爆肝实战项目,后续还会上新更多项目,目标是将所学知识开发成项目并且分享给大家,如知识付费系统, Ai系统, CMS系统,在线商城系统,等等 ,欢迎点击围观

摘要
Java中重载和重写经常搞混:重载是同一个类里方法名相同、参数列表不同的多个方法,编译期就确定调用哪个;重写是子类重新实现父类同签名的方法,运行时动态绑定,是多态的核心。

重载(Overload)与重写(Override)的区别

这两个概念名字很像,但完全是两回事。重载发生在同一个类里,重写发生在父子类之间。下面从多个维度对比。


一、一句话概括

概念 一句话
重载 Overload 同一个类中,方法名相同、参数列表不同的多个方法
重写 Override 子类重新实现父类中方法签名相同的方法

二、核心区别对比表

对比维度 重载 Overload 重写 Override
发生位置 同一个类中 父类与子类之间
方法名 必须相同 必须相同
参数列表 必须不同(个数/类型/顺序) 必须相同
返回值类型 可以不同 必须相同(或是其子类型,协变返回)
访问修饰符 无限制 不能比父类更严格
异常 无限制 不能抛出比父类更宽的检查异常
绑定时机 编译时(静态绑定) 运行时(动态绑定/多态)
多态体现 否 是(运行时多态)
static 方法 可以重载 不能重写(但可被隐藏)
final 方法 可以重载 不能重写
private 方法 可以重载 不能重写(子类看不到)

三、重载(Overload)详解

定义

在同一个类中,定义多个同名但参数不同的方法。

示例(就是你之前看到的 Response)

public class Response<T> {
    public static <T> Response<T> success() { ... }                    // 无参
    public static <T> Response<T> success(T data) { ... }              // 一个参数
    public static <T> Response<T> success(String msg, T data) { ... }  // 两个参数
}

三个 success,参数列表不同 → 重载。

关键规则

  • 只看参数列表(个数、类型、顺序),与返回值无关。
  • 返回值不同不算重载,会编译报错:
public int foo() { return 1; }
public String foo() { return "a"; }  // ❌ 编译错误:仅返回值不同不算重载
  • 调用哪个方法在编译期就确定了(静态绑定)。

常见用途

  • 提供多种调用方式,方便使用(如上面的 success)。
  • 构造器重载(new ArrayList() / new ArrayList<>(10))。

四、重写(Override)详解

定义

子类重新实现父类中已有的方法,要求方法签名(方法名 + 参数列表 + 返回值)一致。

示例

class Animal {
    public void sound() {
        System.out.println("动物叫");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {           // 重写父类方法
        System.out.println("汪汪汪");
    }
}

关键规则

  1. 方法名、参数列表必须相同。
  2. 返回值必须相同,或是父类返回值的子类型(协变返回)。
  3. 访问权限不能变小:父类 public,子类不能改成 protected。
  4. 不能抛出更宽的检查异常。
  5. private、static、final 方法不能被重写。
  6. 建议加 @Override 注解,编译器帮你检查是否写错。

多态体现

Animal a = new Dog();
a.sound();   // 输出"汪汪汪",运行时才决定调用子类方法

这就是运行时多态——调用哪个方法在运行时才确定(动态绑定)。


五、一个直观的类比

想象一家餐厅的菜单:

  • 重载:菜单上有「咖啡」、「咖啡加奶」、「咖啡加奶加糖」——同一类东西,参数不同。
  • 重写:老店有「招牌菜」,新分店把「招牌菜」的做法改了,但菜名一样——子类改了父类的实现。

六、放在一起的完整示例

class Parent {
    public void print() {
        System.out.println("父类 print");
    }
}

class Child extends Parent {

    // ✅ 重写:方法名、参数、返回值都相同
    @Override
    public void print() {
        System.out.println("子类 print");
    }

    // ✅ 重载:在子类中新增一个同名但参数不同的方法
    public void print(String msg) {
        System.out.println("子类 print: " + msg);
    }
}

public class Test {
    public static void main(String[] args) {
        Child c = new Child();
        c.print();           // 重写 → "子类 print"
        c.print("hello");    // 重载 → "子类 print: hello"

        Parent p = new Child();
        p.print();           // 多态 → "子类 print"(运行时决定)
    }
}

注意:Child 中既有重写(print())又有重载(print(String)),两者可以共存。


七、最容易混淆的点

疑问 答案
参数不同但方法名相同,是重写吗? ❌ 不是,那是重载(或子类新增方法)
返回值不同算重载吗? ❌ 不算,编译报错
重写能改参数吗? ❌ 不能,一改就变成重载了
重载是运行时多态吗? ❌ 不是,重载是编译期决定的
重写是运行时多态吗? ✅ 是,这是多态的核心机制
static 方法能被重写吗? ❌ 不能,但可以"隐藏"(隐藏是另一个概念)

八、总结记忆口诀

重载看参数,同类里发生,编译期决定。 重写看签名,子父类之间,运行期决定。

重载 重写
位置 同类 父子类
参数 必须不同 必须相同
绑定 编译时 运行时
多态 否 是
关键字 无 @Override

理解这两者的关键:重载是"同名不同参",重写是"同名同参、子类改写父类逻辑"。

上一篇 @Valid 注解和@Validated注解有什么区别?
下一篇 SpringBoot框架@RestController 注解用法详解

全部评论(0)

头像
😃 😁 😅 😂 😍 😜 😝 🤑 🥵 🥰 😙 😎 😵 😭 😱 😖 🥳 👽 🙈 🤡 😤 💣 💯 💢 ❤️ 👍 👏 👋 👌 🤏 🙏
还没有任何评论哟~
微信扫一扫
微信二维码
微信客服
QQ 咨询
QQ二维码
工作日 9:00 - 18:00 在线
QQ客服
在线工单
提交问题工单,我们会尽快回复处理。
提交工单
在线工单