多态

多态是指同一个父类或接口引用,在运行时可以表现出不同子类对象的行为。

基本形式

Animal animal = new Cat();
animal.sound();
  • 编译时类型:Animal
  • 运行时类型:Cat
  • 调用重写方法时,实际执行 Cat 的方法。

多态成立条件

  1. 存在继承或接口实现关系。
  2. 子类重写父类方法,或实现接口方法。
  3. 父类/接口引用指向子类对象。

编译看左边,运行看右边

  • 编译时看引用类型(父类),决定“能调用哪些成员”。
  • 运行时看实际对象类型,决定“执行哪个重写方法”。
Animal a = new Cat();
a.sound(); // 可以调用,因为 Animal 中有 sound()
// a.catchMouse(); // 不可以,除非 Animal 中声明了该方法

向上转型

子类对象赋值给父类引用:

Animal a = new Cat();

优点是让代码依赖更抽象的类型便于扩展。比如方法参数写成父类或接口:

void makeSound(Animal animal) {
    animal.sound();
}

向下转型

把父类引用转回子类类型:

if (a instanceof Cat) {
    Cat c = (Cat) a;
    c.catchMouse();
}

向下转型前通常用 instanceof 判断,避免 ClassCastException

多态的价值

  • 调用者面向父类或接口编程,不依赖具体类。
  • 新增子类时,原有调用代码通常不需要修改。
  • 配合抽象类接口与实现实现开闭原则。

相关:子类与继承接口回调与上转型运用Object类