Skip to content

多态

多态 是指同一个行为具有多个不同的表现形式。

多态优缺点

优点:

  1. 极大的减少了代码冗余,无需定义多个重载的方法;

缺点:

  1. 在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法。但是由于声明为父类的引用,导致我们没有办法直接调用子类特有的属性和方法。

多态存在的 3 个必要条件:

  • 继承:子类必须继承自父类,才可以实现多态;
  • 重写:子类须对父类中的方法实现重写;
  • 父类的引用指向子类对象Person p = new Child();
java
class Person {
  String name;

  public void eat() {
    System.out.println("eating...");
  }
}
java
class Man extends Person {
  boolean isSmoking;
  String name;

  @Override
  public void eat() {
    System.out.println("man eating.");
  }

  public void saveMoney() {
    System.out.println("man save money.");
  }
}
java
public static void main(String[] args) {
  //常规调用
  Person p1 = new Person();
  Man m1 = new Man();

  //多态调用(父类的引用指向子类对象)
  Person p2 = new Man();
}

虚方法调用

虚方法 是实现多态的重要机制。简单来说,就是当通过父类引用调用一个被重写的方法时,实际执行的是子类的版本,这就是动态绑定。

使用多态调用一个方法:

  • 编译时,认为方法是左边声明的父类中中的方法(即被重写的方法);
  • 执行时,实际执行的是子类重写父类的方法;

简单记忆:编译看左边,执行看右边。

java
Person p2 = new Man();
p2.eat(); // man eating.

上面的方法可以使用 Ctrl + 鼠标左键 进入类中查看方法,可以发现进去的是父类中的方法,但是在程序运行时,输出的结果却是子类方法的内容。

适用性

注意

在多态中,只对类中的方法构成多态,对属性不构成多态

java
Person p2 = new Man();
p2.name = "王一博"; //此时更改的是 Person 中的 name 属性,Man 中的 name 属性并未发生变化

System.out.println(p2.name); //王一博
System.out.println(m1.name); //null

应用场景

声明一个 Animal 类,并且 Dog 类继承自 Animal 类,我们可以只声明一个方法,该方法接受的参数为父类,但是我们传递的时候可以传递子类。

java
public class Animal {
  public void eat() {
    System.out.println("Animal eat");
  }

  public void sleep() {
    System.out.println("Animal sleep");
  }
}

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

  @Override
  public void sleep() {
    System.out.println("Dog sleep");
  }
}
java
public class AnimalTest {
  public static void main(String[] args) {
    AnimalTest test = new AnimalTest();

    test.adopt(new Animal());
    test.adopt(new Dog());
  }

  public void adopt(Animal animal) {
    animal.eat();
    animal.sleep();
  }
}

Released under the MIT License.