多态的定义:
在程序执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
这句话很抽象,我相信很多人看完第一遍之后完不懂什么意思,我当时也是一样,甚至都不想看它。那么我们用一个实际的例子,以及内存图来分析一下。
加入我们先定义一个基类(也可以说是父类)Animal
public class Animal {
private String name;
public Animal(String name){
this.name = name;
}
public void enjoy(){
System.out.println("叫声...");
}
}
然后我们再定义两个它的子类,Cat AND Dog去继承它,以及去重写父类中的方法enjoy。
public class Cat extends Animal{
public String eye;
public Cat(String name, String eye) {
super(name);
this.eye = eye;
}
public void enjoy(){
System.out.println("猫叫...");
}
}
public class Dog extends Animal {
private String sfurColor;
public Dog(String name, String sfurColor){
super(name);
this.sfurColor = sfurColor;
}
public void enjoy(){
System.out.println("阿狗在叫...");
}
}
然后我们在定义一位女士。
public class Lady {
private String name;
private Animal pet;
public Lady(String name, Animal pet) {
this.name = name;
this.pet = pet;
}
public void enjoy(){
pet.enjoy();
}
}
我们来测试一下。
public class Duotai {
public static void main(String[] args) {
Cat c = new Cat("c1", "blue");
Lady l1 = new Lady("l1", c);
l1.enjoy(); //输出:猫叫...
}
}
在解释其原理时我先再说一个知识点,那就是对象转型。
定义:父类引用指向子类对象,那么它只能看到父类的属性和方法。子类的所有成员变量以及方法都不能访问。
画个图:假如说有这样一条语句 Animal a = new Cat();
那么这时候,a就只能访问Animal里面的name而Cat类里面的eye它不能访问。
那么根据刚刚上面所说的,在Lady类里面的Animal pet,在方法enjoy里面应该输出的是 叫声... ,然而我们实际的输出并不是,这是为什么呢?我们还是来画一下内存图。
这里我们可以看到pet是Animal类型的,它指向了Cat,应该调用Animal的enjoy,而实际它是根据c来调用的enjoy方法,所以这里输出了猫叫。
我想看到这里应该可以大致理解多态了。总结出来多态的三个必要条件,(1)继承 (2)重写 (3)父类引用指向子类对象