1. 重写
1.1 概念
重写(Override)是面向对象编程中的一个重要概念,它允许子类重新定义(覆盖)从父类中继承而来的方法,以改变方法的实现和行为。通过重写,子类可以根据自身的需要修改或扩展继承的方法,实现多态性。
1.2 规则
-
继承关系:重写只能在存在继承关系的类之间进行。子类继承了父类的方法,可以选择性地对某些方法进行重写。
-
方法签名:重写的方法必须与父类方法具有相同的名称、参数列表和返回类型。方法签名包括方法名和参数列表,不包括返回类型。
-
访问修饰符:重写的方法可以具有相同的或更高的访问级别。子类中重写的方法不能比父类中的方法具有更低的访问级别。例如,如果父类中的方法是 protected,那么子类中重写的方法可以是 public 或 protected,但不能是 private或default。
-
异常:子类中重写的方法可以抛出与父类方法相同的异常,或者不抛出异常。子类中重写的方法不能抛出比父类方法更宽泛的异常。
-
@Override 注解:Java 中可以使用 @Override 注解来明确标记一个方法是重写的方法。这样做有助于编译器检查是否正确地进行了重写。
-
调用方式:重写方法可以通过父类的引用变量调用,也可以通过子类的实例调用。当使用父类的引用变量调用重写方法时,实际调用的是子类中重写的方法。这就体现了多态性的特点。
1.3 示例代码
class Animal {
public void makeSound() {
System.out.println("Animal makes sound");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Cat meows");
}
}
public class Main {
public static void main(String[] args) {
Animal animal1 = new Animal();
animal1.makeSound(); // 输出 "Animal makes sound"
Animal animal2 = new Cat();
animal2.makeSound(); // 输出 "Cat meows"
}
}
在上面的代码中,Animal 类有一个 makeSound() 方法,Cat 类继承自 Animal 类并重写了 makeSound() 方法。在 main 方法中,创建了一个 Animal 类的实例 animal1 和一个 Cat 类的实例 animal2。当分别调用它们的 makeSound() 方法时,animal1.makeSound() 实际上调用的是 Animal 类中的方法,输出 “Animal makes sound”;而 animal2.makeSound() 调用的是 Cat 类中重写的方法,输出 “Cat meows”。
通过重写,子类可以根据自身的需要修改或扩展继承的方法的行为,实现多态性和灵活性。重写是面向对象编程中非常重要的概念,能够提高代码的可维护性和可扩展性。
2. 重载
2.1 概念
重载(Overload)是面向对象编程中的一个重要概念,它允许在同一个类中定义多个具有相同名称但参数列表不同的方法。通过重载,可以为相似功能的操作提供统一的方法名,并根据不同的参数类型或个数来区分它们,从而实现更灵活的方法调用方式。
2.2 规则
-
方法签名:重载的方法必须具有不同的参数列表,包括参数的个数、类型或顺序。返回类型不属于方法签名的一部分,因此重载的方法可以具有相同的返回类型。
-
参数类型:重载的方法可以使用不同类型的参数,例如整数、浮点数、字符串等。方法参数的类型和顺序不同都可以构成重载。
-
返回类型:重载的方法可以具有相同的或不同的返回类型。方法的返回类型不参与重载的判定。
-
访问修饰符:重载的方法可以具有相同的或不同的访问级别。例如,一个方法可以是 public,另一个可以是 private。
-
异常:重载的方法可以抛出相同的异常,也可以不抛出异常。
-
调用方式:当调用重载的方法时,编译器会根据传入的参数类型和个数选择合适的重载版本。
2.3 示例代码
class Calculator {
public int add(int a, int b) {
return a + b;
}
public double add(double a, double b) {
return a + b;
}
}
public class Main {
public static void main(String[] args) {
Calculator calculator = new Calculator();
int result1 = calculator.add(2, 3); // 调用第一个 add 方法
double result2 = calculator.add(2.5, 3.5); // 调用第二个 add 方法
System.out.println(result1); // 输出 5
System.out.println(result2); // 输出 6.0
}
}
在上面的代码中,Calculator 类中定义了两个 add 方法,一个接收两个整数作为参数,另一个接收两个浮点数作为参数。在 main 方法中,创建了一个 Calculator 类的实例,并分别调用了这两个重载的 add 方法,得到了不同的结果。
通过重载,可以为相似功能的操作提供统一的方法名,根据不同的参数类型或个数来区分它们,从而实现更灵活的方法调用方式。重载是面向对象编程中非常常用的技术之一,能够简化代码结构,提高代码的可读性和可维护性。
3. 总结
3.1 含义
- 重载:在同一个类中定义多个具有相同名称但参数列表不同的方法,以实现更灵活的方法调用方式。
- 重写:子类重新定义父类中的方法,要求方法名称、参数列表和返回类型完全相同,以改变方法的实现和行为。
3.2 目的
- 重载:为相似功能的操作提供统一的方法名,并根据不同的参数类型或个数来区分它们,从而实现更灵活的方法调用方式。
- 重写:让子类能够根据自身的需要修改或扩展继承的方法,实现多态性和灵活性。
3.3 区别
- 参数列表:重载的方法必须具有不同的参数列表,包括参数的个数、类型或顺序;而重写的方法必须与父类方法具有相同的名称、参数列表和返回类型。
- 定义位置:重载发生在同一个类中,通过定义多个方法来实现;而重写发生在子类中,子类重新定义父类中的方法。
- 调用方式:重载根据传入的参数类型和个数选择合适的重载版本;而重写是通过父类的引用变量调用子类中重写的方法,实现多态性。
- 实现方式:重载是编译时多态,即在编译时确定要调用哪个方法;而重写是运行时多态,即在运行时根据具体类型动态地确定要调用哪个方法。