1.如何理解多态?
多态从语文上的理解,多是指数量众多或品种丰富,态指的是事物的形态、状态、行为。
因此多态是事物的多种形态、状态、行为。
上述概念:可引申为同一个事物在不同的情景下拥有不同的行为。
例如:我们自己(同一事物)在教室的时候会学习,而我们在家里时会玩游戏。
在java语言中的多态指同一个引用变量指向不同的实例时执行不同的操作。
从上述例子来看就不难理解了,
同一个引用变量:我们自己,
指向不同实例:呆在学校或家里,
不同的行为:学习、打游戏。
2.多态的使用
2.1多态的三个必要条件
提及三个必要条件之前,我们要理解父类和子类的关系,可以是子类extends关键字继承父类,也可以是类implements实现接口,这时接口可以看成是父类,实现类可以看成是子类。
1.继承(子类继承父类的属性和行为)
2.重写(子类重写父类方法)
3.父类引用指向子类对象(父类 名字 = new 子类())
2.2.使用
//假定Pet宠物类是父类 Dog类 和 Cat类继承自Pet类 并且已经重写Pet类的say方法
Pet dog = new Dog();
//显示汪汪汪
dog.say();
Pet cat = new Cat();
//显示喵喵喵
cat.say();
3.多态的好处
1.多态的两个必要条件是继承和重写,继承是将两个存在IS-A关系的类的重复代码抽出封装成父类,重写是子类需要用到父类的方法但是需要不同行为时,对父类方法重写,因此第一条好处是减少了代码的冗余性,提高了代码的复用性。
2.多态的一个必要条件是父类引用指向子类对象,这里的子类对象可以有很多种,因此我们写代码时可以很灵活的替换掉子类对象,这提高了程序的可拓展性。
4.多态面临的问题和解决方案
在了解我们多态可能遇到的问题之前,先了解一下两个概念:
1.向上转型:指子类对象在赋值给父类时会自动转为父类类型的对象。
Pet dog = new Dog();
2.向下转型:指父类对象想要赋值给子类对象要进行的强制类型转换,转换为子类对象。
Pet dog1 = new Dog();
Dog dog2 = (Dog)dog1;
4.1遇到的问题
在上面代码的实例中如果我们做个小小的改造如下:
Pet dog1 = new Dog();
Cat cat = (Cat)dog1;
这段代码在编译阶段不会报错,但在运行时会爆出ClassCastEexception(类转换异常),结果图如下:
原因是:我们创建了一个狗的实例对象然后将它赋值给我们父类引用dog1,然后我们要把这个dog1向下转型成Cat的实例对象,然后赋值给Cat类型的引用,我们父类引用dog1本质上是Dog类型的实例,但是我们要把Dog类型的实例强转成Cat类型的实例,当然不行,发生了ClasscastException(类转换异常)。
4.2解决方案
那么我们如何解决呢?
java中提供了一个关键字instanceof,它能检测一个类是否实现了某个接口或者一个实例对象是否属于一个类。
语法格式:
实例对象 Instanceof 类(或接口)
该语句的值只有true,false,当对象是右边类或子类的对象时返回true,反之false;
接下来对上面的代码进行改造
//向上转型
Pet dog1 = new Dog();
//向下转型
if(dog1 instanceof Cat){
Cat cat = (Cat)dog1;
}
else if(dog1 instanceof Dog){
Dog d = (Dog)dog1;
}