面向对象编程基础:多态¶
1. 什么是多态?¶
多态(Polymorphism)是面向对象编程(OOP)的三大特性之一,另外两个是封装和继承。多态允许我们使用统一的接口来处理不同类型的对象。简单来说,多态意味着“一个接口,多种实现”。
多态的核心思想是:同一个方法在不同的对象中可以有不同的行为。这使得代码更加灵活和可扩展。
1.1 多态的类型¶
在Java中,多态主要分为两种类型:
- 编译时多态(静态多态):通过方法重载(Overloading)实现。方法重载是指在同一个类中定义多个同名方法,但参数列表不同。
- 运行时多态(动态多态):通过方法重写(Overriding)实现。方法重写是指子类重新定义父类中的方法。
2. 多态的实现¶
2.1 方法重载(编译时多态)¶
方法重载是指在同一个类中定义多个同名方法,但这些方法的参数列表不同(参数类型、参数数量或参数顺序不同)。编译器在编译时根据方法签名来决定调用哪个方法。
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 Main {
public static void main(String[] args) {
Calculator calc = new Calculator();
System.out.println(calc.add(2, 3)); // 调用int add(int a, int b)
System.out.println(calc.add(2.5, 3.5)); // 调用double add(double a, double b)
System.out.println(calc.add(2, 3, 4)); // 调用int add(int a, int b, int c)
}
}
解释: - Calculator
类中有三个add
方法,它们的参数列表不同。 - 在main
方法中,根据传入的参数类型和数量,编译器会自动选择合适的方法进行调用。
2.2 方法重写(运行时多态)¶
方法重写是指子类重新定义父类中的方法。在运行时,JVM会根据对象的实际类型来决定调用哪个方法。
class Animal {
public void makeSound() {
System.out.println("Animal is making a sound");
}
}
class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Dog is barking");
}
}
class Cat extends Animal {
@Override
public void makeSound() {
System.out.println("Cat is meowing");
}
}
public class Main {
public static void main(String[] args) {
Animal myAnimal = new Animal(); // 创建Animal对象
Animal myDog = new Dog(); // 创建Dog对象,但引用类型为Animal
Animal myCat = new Cat(); // 创建Cat对象,但引用类型为Animal
myAnimal.makeSound(); // 调用Animal类的makeSound方法
myDog.makeSound(); // 调用Dog类的makeSound方法
myCat.makeSound(); // 调用Cat类的makeSound方法
}
}
解释: - Animal
类有一个makeSound
方法。 - Dog
和Cat
类分别重写了makeSound
方法。 - 在main
方法中,myDog
和myCat
的引用类型是Animal
,但实际类型是Dog
和Cat
。因此,调用makeSound
方法时,JVM会根据实际类型来决定调用哪个方法。
2.3 多态的应用:接口和抽象类¶
多态不仅可以通过继承实现,还可以通过接口和抽象类来实现。
interface Shape {
void draw();
}
class Circle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Circle");
}
}
class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("Drawing a Rectangle");
}
}
public class Main {
public static void main(String[] args) {
Shape myShape1 = new Circle(); // 创建Circle对象,但引用类型为Shape
Shape myShape2 = new Rectangle(); // 创建Rectangle对象,但引用类型为Shape
myShape1.draw(); // 调用Circle类的draw方法
myShape2.draw(); // 调用Rectangle类的draw方法
}
}
解释: - Shape
接口定义了一个draw
方法。 - Circle
和Rectangle
类实现了Shape
接口,并分别实现了draw
方法。 - 在main
方法中,myShape1
和myShape2
的引用类型是Shape
,但实际类型是Circle
和Rectangle
。因此,调用draw
方法时,JVM会根据实际类型来决定调用哪个方法。
3. 多态的优势¶
- 代码复用:通过多态,我们可以编写通用的代码来处理不同类型的对象。
- 可扩展性:新增子类时,不需要修改现有的代码,只需添加新的实现即可。
- 灵活性:多态使得代码更加灵活,可以在运行时决定调用哪个方法。
4. 练习题¶
4.1 简单练习¶
- 创建一个
Vehicle
类,包含一个start
方法。然后创建两个子类Car
和Bike
,分别重写start
方法。在main
方法中,使用多态调用start
方法。
4.2 中等练习¶
- 创建一个
BankAccount
类,包含一个calculateInterest
方法。然后创建两个子类SavingsAccount
和CurrentAccount
,分别重写calculateInterest
方法。在main
方法中,使用多态调用calculateInterest
方法。
4.3 复杂练习¶
- 创建一个
Employee
类,包含一个calculateSalary
方法。然后创建三个子类Manager
、Developer
和Intern
,分别重写calculateSalary
方法。在main
方法中,使用多态调用calculateSalary
方法,并计算所有员工的总工资。
5. 总结¶
- 多态是面向对象编程的核心概念之一,允许我们使用统一的接口来处理不同类型的对象。
- 方法重载是编译时多态,通过不同的参数列表来实现。
- 方法重写是运行时多态,通过子类重写父类方法来实现。
- 多态可以通过继承、接口和抽象类来实现。
- 多态的优势包括代码复用、可扩展性和灵活性。
通过理解和掌握多态,你可以编写更加灵活和可扩展的代码,提高代码的复用性和可维护性。