多态的转型分为向上转型与向下转型两种:
向上转型:
其实就是把子类类型的对象 赋值给 父类类型的引用,这个过程是自动转换的,类似基本数据类型的自动类型转换
格式:
父类类型 变量名 = new 子类类型();
如:Animal a = new Cat();
向下转型:
父类类型向子类类型向下转换的过程,这个过程是强制的,类似基本数据类型的强制类型转换
格式:
子类类型 变量名 = (子类类型) 父类变量名;
如:Cat c =(Cat) a;
向下转型一旦没有注意,就会出现类型转换异常:ClassCastException,所以应该在转型之前先判断一下是否能转型
代码举例
定义类:
abstract class Animal {
abstract void eat();
}
class Cat extends Animal {
public void eat() {
System.out.println("吃鱼");
}
public void catchMouse() {
System.out.println("抓老鼠");
}
}
class Dog extends Animal {
public void eat() {
System.out.println("吃骨头");
}
public void watchHouse() {
System.out.println("看家");
}
}
转型的过程中,一不小心就会遇到这样的问题,请看如下代码:
public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
Dog d = (Dog)a;
d.watchHouse(); // 调用的是 Dog 的 watchHouse 【运行报错】
}
}
instanceof关键字
为了避免ClassCastException的发生,Java提供了 instanceof
关键字,给引用变量做类型的校验,格式如下:
变量名 instanceof 数据类型
如果变量属于该数据类型,返回true。
如果变量不属于该数据类型,返回false。
所以,转换前,我们最好先做一个判断,代码如下:
public class Test {
public static void main(String[] args) {
// 向上转型
Animal a = new Cat();
a.eat(); // 调用的是 Cat 的 eat
// 向下转型
if (a instanceof Cat){
Cat c = (Cat)a;
c.catchMouse(); // 调用的是 Cat 的 catchMouse
} else if (a instanceof Dog){
Dog d = (Dog)a;
d.watchHouse(); // 调用的是 Dog 的 watchHouse
}
}
}