目录

一、多态的基石:重载与重写的存在意义

二、方法重载:编译期的优雅适配(静态多态)

2.1 重载的合法条件(面试必背)

2.2 重载实战代码演示

2.3 重载的本质:静态绑定

三、方法重写:运行期的动态绽放(动态多态)

3.1 重写严格语法契约

3.2 重写实战代码演示

3.3 重写本质:动态绑定(真正的多态)

四、super 配合重写:保留父类逻辑,优雅扩展

五、重载 VS 重写:万字长文最清晰对比

六、通俗类比总结:看懂 Java 多态的设计智慧


 

如果说继承是 Java 面向对象世界的纵向血脉传承,那么重载、重写与多态,就是程序世界的横向行为绽放。继承让类与类之间拥有了父子层级与代码复用的能力,而重载与重写,让同一套方法名拥有了截然不同的执行逻辑,最终构筑起 Java 最精髓、最优雅的多态体系。

很多开发者初学 Java 时,总把重载与重写混为一谈,误以为都是“改写方法”。殊不知二者在设计思想、语法约束、运行机制上有着天壤之别。重载是编译期的灵活适配,重写是运行期的动态绽放。本文从底层原理、语法契约、代码实战、核心区别层层拆解,带你彻底吃透多态的底层设计智慧。

一、多态的基石:重载与重写的存在意义

面向对象三大特性:封装、继承、多态。如果说封装保证了代码安全,继承实现了代码复用,那么多态就赋予了程序无限的扩展性与灵活性

在真实业务场景中,同一类行为往往需要适配不同场景、不同参数、不同子类逻辑。例如:计算器可以计算两个数、三个数;动物可以发出叫声,但猫是喵喵、狗是汪汪、鸟是叽叽。

如果没有重载与重写,我们只能不断定义不同名称的方法,代码臃肿混乱、可读性极差。而重载与重写,用两套优雅的机制完美解决了这一问题:

重载:同一个类中,方法名相同、参数不同,适配不同入参场景

重写:父子类中,方法签名完全一致,子类覆盖父类行为,实现个性化逻辑

二者一静一动、一编译一运行,共同撑起了 Java 多态的整片天空。

二、方法重载:编译期的优雅适配(静态多态)

重载(Overload)是同一个类内部的方法复用艺术。它允许多个方法拥有完全相同的方法名,只要参数列表存在差异,即可构成合法重载。

重载的核心思想:同名不同参,一法多适配

2.1 重载的合法条件(面试必背)

满足以下参数列表差异任意一种,即为重载:

1. 参数个数不同

2. 参数类型不同

3. 参数顺序不同(不推荐开发使用)

重点误区:返回值不同、修饰符不同、方法权限不同,无法构成重载

2.2 重载实战代码演示

我们以通用计算器为例,实现多组重载方法,适配不同计算场景:

public class Calculator {

    // 两数相加
    public int add(int a, int b) {
        return a + b;
    }

    // 重载1:参数个数不同
    public int add(int a, int b, int c) {
        return a + b + c;
    }

    // 重载2:参数类型不同
    public double add(double a, double b) {
        return a + b;
    }

    public static void main(String[] args) {
        Calculator cal = new Calculator();
        System.out.println(cal.add(1, 2));         // 调用双int
        System.out.println(cal.add(1, 2, 3));       // 调用三int
        System.out.println(cal.add(1.5, 2.5));      // 调用double
    }
}

2.3 重载的本质:静态绑定

重载发生在编译期。编译器根据传入的参数类型、参数个数,直接锁定调用哪一个方法,程序运行时不再动态判断。因此重载也被称为静态多态

它的作用是:统一行为语义,让同类操作统一入口,代码更加整洁统一。

三、方法重写:运行期的动态绽放(动态多态)

重写(Override)是父子继承体系中的行为重塑。子类继承父类后,对父类原有方法的逻辑进行覆盖、改造、优化,保留方法声明,替换内部实现。

重写的核心思想:沿用父类契约,实现子类个性

3.1 重写严格语法契约

重写必须严格遵守“三同一不小一大”:

1. 同方法名、同参数列表、同返回值(协变返回除外)

2. 访问权限:子类权限 不能更严格(public > protected > default > private)

3. 异常声明:子类抛出异常不能比父类更大

4. private、static、final 方法不能被重写

3.2 重写实战代码演示

我们以动物发声场景,完美体现重写的多态魅力:

// 父类:动物
class Animal {
    public void shout() {
        System.out.println("动物发出叫声");
    }
}

// 子类:猫,重写发声方法
class Cat extends Animal {
    @Override
    public void shout() {
        System.out.println("小猫喵喵喵");
    }
}

// 子类:狗,重写发声方法
class Dog extends Animal {
    @Override
    public void shout() {
        System.out.println("小狗汪汪汪");
    }
}

public class OverrideDemo {
    public static void main(String[] args) {
        // 父类引用指向子类对象:多态核心写法
        Animal a1 = new Cat();
        Animal a2 = new Dog();

        a1.shout();
        a2.shout();
    }
}

运行结果

小猫喵喵喵

小狗汪汪汪

3.3 重写本质:动态绑定(真正的多态)

重写发生在运行期。编译时只识别父类方法签名,运行时 JVM 根据真实对象类型动态绑定子类重写方法。

这就是 Java 多态最核心的魅力:父类引用、子类实现,一套接口,多种行为

四、super 配合重写:保留父类逻辑,优雅扩展

重写并非完全抛弃父类逻辑,更多时候是在父类基础上增强扩展。借助 super 关键字,可以在子类重写方法中调用父类原方法。

class Person {
    public void showInfo() {
        System.out.println("这是一个普通人");
    }
}

class Student extends Person {
    @Override
    public void showInfo() {
        // 先执行父类原有逻辑
        super.showInfo();
        // 再扩展子类独有逻辑
        System.out.println("这是一名学生,正在学习Java");
    }
}

public class SuperOverrideDemo {
    public static void main(String[] args) {
        new Student().showInfo();
    }
}

这种模式是开发中最常用的重写写法:复用父类、扩展子类,不重复造轮子。

五、重载 VS 重写:万字长文最清晰对比

对比维度

重载 Overload

重写 Override

发生范围

同一个类内部

父子继承关系之间

方法签名

方法名相同,参数不同

方法名、参数、返回值完全一致

绑定时机

编译期静态绑定

运行期动态绑定

权限影响

权限无关

子类权限不能更严格

多态类型

静态多态

动态多态(真正多态)

核心作用

统一方法名,适配多参数场景

子类个性化重定义父类行为

六、通俗类比总结:看懂 Java 多态的设计智慧

用「厨师做菜」完美理解重载与重写:

重载(同一厨师):同一个厨师,可以炒青菜、炒肉、炒饭,方法名都叫“炒菜”,食材参数不同,做法不同。同一能力,适配不同场景

重写(师徒传承):师傅会做“招牌菜”,徒弟学了手艺之后,改良配方、优化口味,保留菜名,重做菜品。继承能力,重塑行为

继承搭建层级,重载统一入口,重写赋予个性,多态成就灵活。这四者相辅相成,构成了 Java 面向对象编程最优雅、最核心的底层设计体系,也是所有高级框架、设计模式的底层基石。

 

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐