多态(polymorphism)从字面意思上来说就是指“多种形态”。
一个父类的引用变量,可以指向一个子类的实例对象,而一个父类可能有多个子类,如我们说“狗是一种哺乳动物”,也可以说“马是一种哺乳动物”、“猫是一种哺乳动物”等等,这里的“哺乳动物”是父类(如用Mammal表示),而狗、马、猫等是“哺乳动物”的子类。如有如下的类定义:
public class Mammal{
…
}
class Dog extends Mammal{
…
}
class Horse extends Mammal{
…
}
class Cat extends Mammal{
…
}
如下的一个“哺乳动物类”的引用animal时:
Mammal animal;
animal可能在程序运行的不同时刻指向了Mammal子类的不同对象。例如,在某个时刻可能指向的是一个狗类(Dog)的实例对象,而在另外一个时刻可能指向的是猫类(Cat)的实例对象或马类(Horse)的实例对象。像animal这样在不同时段内可以指向不同类型对象的引用,就是多形态的引用。
Java的多态性就是指方法的多态和引用的多态。
在Java语言中,多态性分两种类型:
1.由方法多态引发的编译时多态性
编译时多态性是由方法重载实现的。前面介绍过,重载是指在同一个类中(也可以是子类与父类中),同一个方法名被定义多次,但所采用的形式参数列表不同(可能是参数的个数、类型或顺序不同)。重载的方法在编译阶段,编译器会根据所调用方法参数的不同,具体来确定要调用的方法。如下面的程序中定义了一个类A:
class A{
…
A(){ … }
A(int x){ … }
A(int x, int y){ … }
…
}
类A中定义了3个重载的构造方法,则在实例化一个对象时,会根据构造方法中实参的类型与个数确定调用类A中的哪个构造方法。如程序中有下面一条语句:
A a = new A(12);
则编译时,系统就可以确定该处要调用类A中有一个参数的构造方法。
2.由引用多态引发的运行时多态性
由于子类继承了父类所有的属性,所以子类对象可以作为父类对象使用。程序中凡是使用父类对象的地方,都可以用子类对象来代替,因此如果说明了一个父类的引用,这个引用就是多形态的引用。
对于多形态的一个引用,调用方法的原则是:Java运行时系统根据调用该方法的实例,来决定调用哪个方法。对子类的一个实例,如果子类重写了父类的方法,则运行时系统调用子类的方法;如果子类继承了父类的方法(未重写),则运行时系统调用父类的方法。 |
|