7.1、多态的概念
多态:用一个引用类型,使用不同的实例而执行不同操作
方法重写是实现多态的基础。
多态意味着在一次方法调用中根据包含的对象的实际类型(即实际的子类对象)来决定应该调用哪个方法,而不是由用来存储对象引用的变量类型决定的。当调用一个方法时,为了实现多态的操作,这个方法既是父类声明过的,也必须是在子类中重写过的方法。
7.2、主人带宠物去找医生看病为例
创建一个包,包中有如下类:
(1)父类Animal类:(父类)
(2)子类Dog类:(宠物类)
(3)子类Penguin类:(宠物类)
(4)主人类Master类:(主人类)
(5)测试类Test类
7.2.1、对案例一和案例二进行解析
如果使用案例1中主人类Master类中给宠物看病的方法,如果此时又需要给XXX宠物看病时,就需要:
(1)添加XXX类,继承父类Animal类;
(2)修改主人类Master类,添加给XXX类宠物看病的方法
解析:
(1)通过案例1可知,假如又养了100种动物,那么就需要不断创建XXX类,并需要不断的在Master类中添加相应的XXX类宠物看病的方法,造成频繁修改代码,代码可扩展性、可维护性差;
(2)并且由案例1知:主人要做的事情只需要把宠物送到医院即可,至于怎么看病、看病的方法,就不需要主人去做了!按照案例1所做的话,则主人就完成了给宠物看病的功能,还需要医生干嘛?
通过上述解析我们就需要使用多态进行优化!如案例2所示通过多态进行优化!
通过案例1和案例2进行对比,解析多态!
7.2.2、案例一:(不建议使用)
7.2.3、案例二:(使用多态进行优化)
上述区别在于:
(1)在子类Dog类中重写toHospital()方法
(2)在子类Penguin类中重写toHospital()方法
(3)在父类Animal类中定义一个去医院看病的toHospital()方法
(4)在主人类Master类定义方法cure()带宠物去看病
(5)测试类Test类
7.2.3.1、案例二总结
7.2.4、多态
如下述代码:
//会调用Dog类的toHospital()方法,而不是Animal类的toHospital()方法,体现了多态
master.cure(animal);//向上转型:父类的引用指向了子类的实例(对象) //Animal为抽象父类,Dog为子类,Animal中也包含抽象方法toHospital() Animal animal = new Dog("旺财", 50, 80, "哈士奇"); //会调用Dog类的toHospital()方法,而不是Animal类的toHospital()方法,体现了多态 master.cure(animal);
7.3、向上转型
7.3.1、向上转型语法格式
子类向父类的转型称为向上转型。
向上转型的语法格式如下:
< 父类型 > < 引用变量名 > = new < 子类型 >
Animal animal = new Dog(); //注:父类为Animal类、子类为Dog类
例如上述7.2.3 案例二中的测试类Test类-->输出结果一样!
package com.bdqn.demo05; public class Test { public static void main(String[] args) { //创建Master类对象 Master master = new Master(); //创建宠物类对象 Cat cat = new Cat("咪咪", 40, 80, "白色"); master.cure(cat); System.out.println(cat.getHealth()); //向上转型:父类的引用指向了子类的实例(对象) Animal animal = new Dog("旺财", 50, 80, "哈士奇"); master.cure(animal); } }
7.3.2、向上转型的概念
之前介绍了基本数据类型之间的类型转换,举例如下:
(1)把int型常量或变量的值赋给double型变量,可以自动进行类型转换。
int i = 5; double d1 = 5;
(2)把double型常量或者变量的值赋给int型变量,必须进行强制类型转换。
double d2 = 3.14; int a = (int)d2;
实际上在引用数据类型的子类和父类之间也存在着类型转换问题,如上述7.2.3 案例二中的测试类Test类中的:
//向上转型:父类的引用指向了子类的实例(对象) //Animal为抽象父类,Dog为子类,Animal中也包含抽象方法toHospital() Animal animal = new Dog("旺财", 50, 80, "哈士奇"); //会调用Dog类的toHospital()方法,而不是Animal类的toHospital()方法,体现了多态 master.cure(animal);
7.3.3、子类转换成父类的规则(向上转型)
(1)将一个父类的引用指向一个子类对象称为向上转型,系统会自动进行类型转换。
(2)此时通过父类引用变量调用的方法是子类覆盖或继承了父类的方法,不是父类的方法。
(3)此时通过父类引用变量无法调用子类特有的方法。
7.4、向下转型