多态是同一个对象,在不同时刻表现出来不同的形态,称之为多态。
多态的前提
多态成员的访问特点(非常重要,一定得理解,请先看口诀,再结合图片下方注意文字,和图片理解)
口诀(父类是左边,子类是右边):
注意:
? ①:先解释下口诀,编译看左边,也就是看左边有无这个成员,有的话编译才通过,我们可以看到图片一和图片二两张都是因为左边父类中无 爆红的这个成员,所以报错
? ②:对于成员变量,编译看左边(也就是看左边父类中有无这个成员,有的话编译通过),执行看左边(我们看第三张图,可以看到最中运行的结果是左边父类中的成员变量值)
? ③:对于成员方法,编译看左边(也就是看左边父类中有无这个成员,有的话编译通过),执行看右边(我们看第三张图,可以看到最中运行的结果是右边子类中的成员方法,因为方法重写了)
好处:提高了程序的扩展性,定义方法的时候,使用父类作为参数,将来在使用的时候使用具体的子类参与操作
弊端:不能使用子类特有的功能(必须父类中有【回想口诀,只有编译通过才行】)
多态的弊端是,不能使用子类特有的功能,怎么办呢?就提出我们多态的转型。
类型 | 方向 | ||
---|---|---|---|
向上转型 | 从子到父 | 父类引用指向子类对象 | Animal a = new Cat(); |
向下转型 | 从父到子 | 父类引用转为子类对象 | Cat b = (Cat)a |
注意:向下转型,有个前提,得是同一种对象
? Animal a = new Cat(); // a 是Animal类型,但是本质是 猫
? Dog d = (Dog)a; // 很明显这行就错了,(Dog)a 相当于强转,但是 猫怎么能转成狗呢!
// 动物类
class Animal{
public void show(){
System.out.println("动物!");
}
}
// 狗类
class Dog extends Animal{
public void show(){
System.out.println("狗!");
}
public void speak(){
System.out.println("汪汪");
}
}
// 猫类
class Cat extends Animal{
public void show(){
System.out.println("猫!");
}
public void eat(){
System.out.println("小鱼干");
}
}
public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
Animal b = new Dog();
// 调用方法(父类对象调用,多态的形式,记得口诀)
a.show();
b.show();
// 编译不通过,因此爆红
/* a.speak();
a.eat();*/
// 向下转型
Cat c = (Cat)a;
Dog d = (Dog)b;
// 调用方法(子类对象调用)
c.eat();
c.show();
d.speak();
d.show();
/* Cat c1 = (Cat)b;
c1.speak();*/
}
}
多态很重要,一定要理解!!!
其他两大特征可参考下面这两篇文章: