重载与重写区别 -Java

重载(Overloading)与重写(Overriding)

在 Java 中,重载(Overloading)和重写(Overriding)是两种常见的多态实现方式,它们的目的不同,但都涉及方法的使用。

1. 重载(Overloading)

重载是指在同一个类中,方法名相同,但参数列表不同的方法。它与返回值类型无关。重载的关键点是方法名相同,但参数类型、数量或顺序有所不同。重载是编译时多态的一种表现,编译器在编译时决定使用哪个方法。

重载的特点:

  • 方法名相同,但参数不同(类型、数量或顺序)。
  • 发生在同一个类中。
  • 不同的重载方法可以有不同的返回类型,但返回类型不是重载的依据。
  • 重载的决定是在编译时进行的(静态多态)。

重载的规则

  1. 方法名必须相同
  2. 参数列表必须不同(可以是参数类型不同、参数数量不同、参数顺序不同)。
  3. 返回类型可以不同,但不作为重载的依据
  4. 访问修饰符抛出的异常可以不同。

重载的代码示例:

class Calculator {
    // 重载加法方法
    public int add(int a, int b) {
        return a + b;
    }

    public double add(double a, double b) {
        return a + b;
    }

    public int add(int a, int b, int c) {
        return a + b + c;
    }
}

public class OverloadExample {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();

        // 调用不同的重载方法
        System.out.println(calculator.add(10, 20));       // 输出: 30
        System.out.println(calculator.add(10.5, 20.5));   // 输出: 31.0
        System.out.println(calculator.add(10, 20, 30));   // 输出: 60
    }
}

输出结果:

30
31.0
60

说明

  • 这里有三个 add 方法,参数不同(一个是 int 类型的两个参数,一个是 double 类型的两个参数,另一个是 int 类型的三个参数),它们的返回类型不同,但都可以正确地重载。

2. 重写(Overriding)

重写是指子类重新定义从父类继承过来的方法,方法签名(包括方法名、返回类型、参数列表)必须保持一致。重写是运行时多态的一种表现,运行时决定使用哪个方法。子类可以根据需要提供自己的实现。

重写的特点:

  • 子类提供自己的实现来替代父类的方法。
  • 方法签名必须完全相同,包括方法名、参数列表、返回类型。
  • 访问权限:子类重写的方法的访问修饰符不能低于父类的方法。即父类方法为 public,子类也必须是 public
  • 抛出的异常:子类重写方法时,抛出的异常不能超过父类方法抛出的异常范围。即,父类方法没有声明异常,子类方法不能声明异常;父类方法声明了某个异常,子类方法可以声明相同或其子类异常。
  • 动态绑定:重写的方法决定于实际对象的类型,而非引用变量的类型。

重写的代码示例:

class Animal {
    // 父类方法
    public void sound() {
        System.out.println("Animal makes a sound");
    }
}

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

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

public class OverrideExample {
    public static void main(String[] args) {
        Animal animal1 = new Dog();
        Animal animal2 = new Cat();

        animal1.sound();  // 输出: Dog barks
        animal2.sound();  // 输出: Cat meows
    }
}

输出结果:

Dog barks
Cat meows

说明

  • sound 方法在 DogCat 中被重写(即子类提供自己的实现)。尽管 animal1animal2 的类型是 Animal,但由于多态机制,调用的实际方法是 DogCat 类中重写后的方法。
  • 动态绑定:实际调用的 sound 方法是由运行时的对象类型决定的。

3. 重载与重写的主要区别

特性 重载(Overloading)重写(Overriding)
方法名 方法名相同 方法名相同
参数 参数列表必须不同(类型、数量、顺序) 参数列表必须完全相同
返回类型 返回类型可以不同 返回类型必须相同
访问修饰符 可以不同 子类重写方法的访问权限不能低于父类方法的访问权限
静态方法 可以重载静态方法(与实例无关) 不能重写静态方法(静态方法是类级别的,不涉及实例)
多态性 发生在编译时,称为静态多态性 发生在运行时,称为动态多态性
父类/子类关系 不需要父子类关系,两个方法只是同名但参数不同的不同方法 需要父类和子类之间的继承关系
用途 适用于提供多个方法名相同但功能不同的版本 适用于子类实现父类的功能(继承和覆盖父类方法)

4. 实际应用场景

  • 重载(Overloading)

    • 重载适用于同一类中需要定义多个功能相似但参数不同的方法。例如,计算器的加法方法可以重载,支持不同的数据类型和不同数量的参数。
    • 常见场景:例如不同类型的输入参数(int, double),相同操作但处理不同数据类型。
  • 重写(Overriding)

    • 重写适用于子类提供自己的实现来覆盖父类的行为。例如,Animal 类的 sound 方法被 Dog 类和 Cat 类重写,分别实现了不同的行为。
    • 常见场景:例如继承体系中,子类根据自己的特性来实现父类的某些方法。

5. 总结

  • 重载:同一方法名,但参数不同,发生在同一类中,编译时决定使用哪个方法。
  • 重写:子类重写父类方法,方法签名相同,发生在继承体系中,运行时决定使用哪个方法。
Java碎碎念 文章被收录于专栏

来一杯咖啡,聊聊Java的碎碎念呀

全部评论

相关推荐

02-02 20:25
门头沟学院 Java
数学转码崽:八股文也算是前人总结的精华,但是因为全是结果导向,你光背不去理解它背后的深层原理和这样做的原因,反而忽略了程序员最该重视的过程导向。推荐你不会的就去多问ai,比如我当时背的时候,concurrenthashmap底层原理常见八股网站都会讲,但是我不理解为什么它去用synchronize锁节点,为什么不用reentrantlock去锁节点。面试官问我你为什么觉得synchronize在这个场景下性能更好呢?虽然面试官可能也不确定清楚,但是你可以尝试给他解答,让他看见你的思考,这才是最重要的,毕竟你没实习,你的项目你也无法证明是你自己思考的产物,那就在别的地方体现你的能力
点赞 评论 收藏
分享
评论
点赞
1
分享

创作者周榜

更多
牛客网
牛客企业服务