跳转至

面向对象编程基础:多态

1. 什么是多态?

多态(Polymorphism)是面向对象编程(OOP)的三大特性之一,另外两个是封装和继承。多态允许我们使用统一的接口来处理不同类型的对象。简单来说,多态意味着“一个接口,多种实现”。

多态的核心思想是:同一个方法在不同的对象中可以有不同的行为。这使得代码更加灵活和可扩展。

1.1 多态的类型

在Java中,多态主要分为两种类型:

  1. 编译时多态(静态多态):通过方法重载(Overloading)实现。方法重载是指在同一个类中定义多个同名方法,但参数列表不同。
  2. 运行时多态(动态多态):通过方法重写(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方法。 - DogCat类分别重写了makeSound方法。 - 在main方法中,myDogmyCat的引用类型是Animal,但实际类型是DogCat。因此,调用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方法。 - CircleRectangle类实现了Shape接口,并分别实现了draw方法。 - 在main方法中,myShape1myShape2的引用类型是Shape,但实际类型是CircleRectangle。因此,调用draw方法时,JVM会根据实际类型来决定调用哪个方法。

3. 多态的优势

  1. 代码复用:通过多态,我们可以编写通用的代码来处理不同类型的对象。
  2. 可扩展性:新增子类时,不需要修改现有的代码,只需添加新的实现即可。
  3. 灵活性:多态使得代码更加灵活,可以在运行时决定调用哪个方法。

4. 练习题

4.1 简单练习

  1. 创建一个Vehicle类,包含一个start方法。然后创建两个子类CarBike,分别重写start方法。在main方法中,使用多态调用start方法。

4.2 中等练习

  1. 创建一个BankAccount类,包含一个calculateInterest方法。然后创建两个子类SavingsAccountCurrentAccount,分别重写calculateInterest方法。在main方法中,使用多态调用calculateInterest方法。

4.3 复杂练习

  1. 创建一个Employee类,包含一个calculateSalary方法。然后创建三个子类ManagerDeveloperIntern,分别重写calculateSalary方法。在main方法中,使用多态调用calculateSalary方法,并计算所有员工的总工资。

5. 总结

  • 多态是面向对象编程的核心概念之一,允许我们使用统一的接口来处理不同类型的对象。
  • 方法重载是编译时多态,通过不同的参数列表来实现。
  • 方法重写是运行时多态,通过子类重写父类方法来实现。
  • 多态可以通过继承接口抽象类来实现。
  • 多态的优势包括代码复用可扩展性灵活性

通过理解和掌握多态,你可以编写更加灵活和可扩展的代码,提高代码的复用性和可维护性。