多态
多态 是指同一个行为具有多个不同的表现形式。
多态优缺点
优点:
- 极大的减少了代码冗余,无需定义多个重载的方法;
缺点:
- 在多态的场景下,我们创建了子类的对象,也加载了子类特有的属性和方法。但是由于声明为父类的引用,导致我们没有办法直接调用子类特有的属性和方法。
多态存在的 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();
}
}