重载与重写区别 -Java
重载(Overloading)与重写(Overriding)
在 Java 中,重载(Overloading)和重写(Overriding)是两种常见的多态实现方式,它们的目的不同,但都涉及方法的使用。
1. 重载(Overloading)
重载是指在同一个类中,方法名相同,但参数列表不同的方法。它与返回值类型无关。重载的关键点是方法名相同,但参数类型、数量或顺序有所不同。重载是编译时多态的一种表现,编译器在编译时决定使用哪个方法。
重载的特点:
- 方法名相同,但参数不同(类型、数量或顺序)。
- 发生在同一个类中。
- 不同的重载方法可以有不同的返回类型,但返回类型不是重载的依据。
- 重载的决定是在编译时进行的(静态多态)。
重载的规则:
- 方法名必须相同。
- 参数列表必须不同(可以是参数类型不同、参数数量不同、参数顺序不同)。
- 返回类型可以不同,但不作为重载的依据。
- 访问修饰符和抛出的异常可以不同。
重载的代码示例:
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
方法在Dog
和Cat
中被重写(即子类提供自己的实现)。尽管animal1
和animal2
的类型是Animal
,但由于多态机制,调用的实际方法是Dog
和Cat
类中重写后的方法。- 动态绑定:实际调用的
sound
方法是由运行时的对象类型决定的。
3. 重载与重写的主要区别
方法名 | 方法名相同 | 方法名相同 |
参数 | 参数列表必须不同(类型、数量、顺序) | 参数列表必须完全相同 |
返回类型 | 返回类型可以不同 | 返回类型必须相同 |
访问修饰符 | 可以不同 | 子类重写方法的访问权限不能低于父类方法的访问权限 |
静态方法 | 可以重载静态方法(与实例无关) | 不能重写静态方法(静态方法是类级别的,不涉及实例) |
多态性 | 发生在编译时,称为静态多态性 | 发生在运行时,称为动态多态性 |
父类/子类关系 | 不需要父子类关系,两个方法只是同名但参数不同的不同方法 | 需要父类和子类之间的继承关系 |
用途 | 适用于提供多个方法名相同但功能不同的版本 | 适用于子类实现父类的功能(继承和覆盖父类方法) |
4. 实际应用场景
-
重载(Overloading):
- 重载适用于同一类中需要定义多个功能相似但参数不同的方法。例如,计算器的加法方法可以重载,支持不同的数据类型和不同数量的参数。
- 常见场景:例如不同类型的输入参数(
int
,double
),相同操作但处理不同数据类型。
-
重写(Overriding):
- 重写适用于子类提供自己的实现来覆盖父类的行为。例如,
Animal
类的sound
方法被Dog
类和Cat
类重写,分别实现了不同的行为。 - 常见场景:例如继承体系中,子类根据自己的特性来实现父类的某些方法。
- 重写适用于子类提供自己的实现来覆盖父类的行为。例如,
5. 总结
- 重载:同一方法名,但参数不同,发生在同一类中,编译时决定使用哪个方法。
- 重写:子类重写父类方法,方法签名相同,发生在继承体系中,运行时决定使用哪个方法。
Java碎碎念 文章被收录于专栏
来一杯咖啡,聊聊Java的碎碎念呀