在 Java 中,重载和重写是两个关键的面向对象编程概念。重载通过方法的参数列表不同来区分同名方法,提供了更灵活的方法调用方式。而重写通过子类重新定义父类中已经存在的方法,实现了多态性的体现,让代码更具可扩展性和维护性。
# 重载(Overloading)
重载是指在同一个类中可以定义多个方法,这些方法具有相同的名称但是参数列表不同。参数列表的不同可以体现在参数的数量、类型或者顺序上。编译器在调用这些方法时,会根据提供的参数类型和数量来选择合适的方法。
示例:
public class OverloadingTest {
// 方法重载,参数类型不同
public void print(int num){
System.out.println("参数(int)为:"+num);
}
// 方法重载,参数类型不同
public void print(String num){
System.out.println("参数(String)为:"+num);
}
// 方法重载,参数数量不同
public void print(int num1,int num2){
System.out.println("参数1(int)为:"+num1+"参数2(int)为"+num2);
}
}
# 重写(Overriding)
重写是指子类重新定义了父类中已经存在的方法。重写的方法与父类中的方法具有相同的名称、返回类型和参数列表。在运行时,会根据对象的实际类型调用相应的子类方法,体现了多态性的概念。
示例:
//动物的父类
public class Animal {
public void call(){
System.out.println("Animal发出声响。。。");
}
}
//Cat继承了Animal,重写了call方法
public class Cat extends Animal{
@Override
public void call() {
System.out.println("喵喵喵,喵喵喵。。。");
}
}
//Dog继承了Animal,重写了call方法
public class Dog extends Animal{
@Override
public void call() {
System.out.println("汪汪汪,汪汪汪。。。");
}
}
在上述例子中,Dog 和 Cat 类分别重写了 call 方法。当通过父类引用调用这个方法时,实际上会根据对象的实际类型调用相应的子类方法。
public class Test {
public static void main(String[] args) {
Animal dog = new Dog();
Animal cat = new Cat();
//dog和cat的引用类型一样,调用相同的方法输出不同
dog.call(); //输出: 汪汪汪,汪汪汪。。。
cat.call(); //输出: 喵喵喵,喵喵喵。。。
}
}
# 区别与应用场景
- 参数不同
重载是通过方法的参数列表不同来区分同名方法的,而重写是通过子类重新定义父类方法来实现的。
- 解析时机(编译时与运行时)
重载是在编译时确定调用哪个方法,而重写是在运行时动态绑定,根据对象的实际类型调用相应的方法。
- 返回值
在重载中,方法的签名包括方法的名称、参数数量、类型和顺序,重载方法的返回值类型不是方法签名的一部分,而重写方法的返回值类型必须与被重写方法的返回值类型相同。
# 为什么返回值不同不算方法重载?
Java编译器在解析方法调用时主要依赖于方法的签名(包括方法名、参数数量、参数类型和参数顺序),而不考虑返回值类型。两个方法如果具有相同的方法签名,就会被视为重载关系。如果只有返回值类型不同,而其他部分相同,编译器无法根据方法的签名区分这两个方法,因为在调用时编译器只关心调用的方法签名,而不关心返回值类型。
# 总结
重载和重写是 Java 中实现多态性的两种方式,它们分别通过方法的参数列表和方法的重写来实现。这两个概念为 Java 提供了更高层次的灵活性和可扩展性,使得代码更易于理解和维护。
在实际应用中,要根据具体的情况选择使用重载还是重写,以便更好地实现程序的设计目标。同时,深刻理解这两个概念对于面向对象编程的理解至关重要。
← 如何理解面向对象 如何理解Java中的多态 →