Skip to content
第 7 章 后端 ⏱ 10 分钟阅读

第 7 章:多态 ​

学习目标 ​

  • 理解多态的本质(同一个调用,不同行为)
  • 掌握向上转型和向下转型
  • 学会 instanceof 和模式匹配
  • 理解多态的实际用途

一、多态三要素 ​

  1. 继承:子类继承父类
  2. 重写:子类重写父类方法
  3. 向上转型:父类引用指向子类对象
java
class Animal {
    public void sound() {
        System.out.println("动物叫");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("汪汪汪");
    }
}

class Cat extends Animal {
    @Override
    public void sound() {
        System.out.println("喵喵喵");
    }
}

// 多态
Animal a1 = new Dog();           // 父类引用指向子类对象
Animal a2 = new Cat();
a1.sound();                       // 汪汪汪(运行时绑定到 Dog 的实现)
a2.sound();                       // 喵喵喵(运行时绑定到 Cat 的实现)

二、多态的实际用途 ​

好处:写一段代码,适用于所有子类。

java
public void handleAnimal(Animal animal) {
    animal.sound();   // 不管传 Dog 还是 Cat,自动调用对应实现
}

handleAnimal(new Dog());   // 汪汪汪
handleAnimal(new Cat());   // 喵喵喵

三、向上转型(自动,安全) ​

java
Dog dog = new Dog();
Animal animal = dog;       // 自动向上转型
animal.sound();             // ✅ 只能调用父类声明的方法
// animal.bark();           // ❌ 编译报错:父类没有 bark

四、向下转型(强制,可能失败) ​

java
Animal animal = new Dog();

// 必须先 instanceof 判断
if (animal instanceof Dog) {       // 类型检查
    Dog dog = (Dog) animal;         // 强制向下转型
    dog.bark();                     // 现在可以调用子类方法
}

⚠️ 坑 1:向下转型前必须 instanceof 判断,否则抛 ClassCastException:

java
Animal animal = new Cat();
Dog dog = (Dog) animal;   // ❌ 运行时 ClassCastException

JDK 16+ 模式匹配(自动转型 + 绑定变量):

java
if (animal instanceof Dog dog) {   // 直接绑定变量
    dog.bark();
}

五、多态的常见应用 ​

1. 数组里放不同子类 ​

java
Animal[] animals = { new Dog(), new Cat(), new Dog() };
for (Animal a : animals) {
    a.sound();   // 自动调用各自的实现
}

2. 方法参数用父类 ​

java
public double totalArea(Shape[] shapes) {  // 传 Shape 子类数组
    double sum = 0;
    for (Shape s : shapes) {
        sum += s.area();                   // 多态调用各自的 area()
    }
    return sum;
}

3. 工厂模式基础 ​

java
public static Animal create(String type) {
    return switch (type) {
        case "dog" -> new Dog();
        case "cat" -> new Cat();
        default -> throw new IllegalArgumentException("未知类型");
    };
}

六、字段没有多态 ​

java
class Parent {
    String name = "父类";
}
class Child extends Parent {
    String name = "子类";
}

Parent p = new Child();
System.out.println(p.name);      // 父类(字段不参与多态,看引用类型)

⚠️ 坑 2:方法有多态,字段没有多态。如果子类定义了和父类同名字段,父类引用访问的是父类字段。

七、本章小结 ​

要点关键
多态三要素继承 + 重写 + 向上转型
向上转型子类 → 父类,自动,只能调父类方法
向下转型父类 → 子类,必须先 instanceof
多态用处参数用父类,自动适配所有子类
字段无多态字段看引用类型,不看实际对象

动手练习 ​

  1. Shape 多态:抽象 Shape 有 area(),子类 Circle / Rectangle 重写,写一个 totalArea(Shape[]) 方法
  2. Employee 体系:Employee → Manager / Developer,各自有 calculateBonus(),演示多态调用
  3. instanceof 练习:写一个 describe(Animal a) 方法,根据实际类型输出不同信息

下一章:第 8 章:抽象类与接口 →

本站基于 VitePress 构建 · 由 StackHub 团队维护