【Java特性】多态详解——对象类型转换与 instanceof 关键字的运用
多态是指不同类的对象在调用同一个方法时所呈现出的多种不同行为。通常来说,在一个类中定义的属性和方法被其他类继承或重写后,当把子类对象直接赋值给父类引用变量时,相同引用类型的变量调用同一个方法所呈现出的多种不同形态。多态不仅解决了方法同名的问题,而且还使程序变的更加灵活,从而有效的提高程序的可扩展性和可维护性。
对象的类型转换
在多态的学习中,涉及到将子类对象当做父类类型使用的情况,此种情况在Java的语言环境中称为“向上转型”,例如下面两行代码:
Animal an1 = new Cat(); // 将Cat类对象当做Animal类型来使用
Animal an2 = new Dog(); // 将Dog类对象当做Animal类型
需要注意的是,此时不能通过父类变量去调用子类特有的方法。
如文件1所示。
文件1 Example16.java
// 定义接口Animal
interface Animal {
void shout(); // 定义抽象shout()方法
}
// 定义Cat类实现Animal接口
class Cat implements Animal {
// 实现接口shout()方法
public void shout() {
System.out.println("喵喵……");
}
// 定义Cat类特有的抓老鼠catchMouse()方法
public void catchMouse() {
System.out.println("小猫抓老鼠……");
}
}
// 定义测试类
public class Example16 {
public static void main(String[] args) {
Animal an1 = new Cat();
an1.shout();
an1.catchMouse();
}
}
程序编译报错,如图1所示。
图1 运行结果
从图1可以看出,程序编译出现了“The method catchMouse() is undefined for the type Anima(在父类Animal中未定义catchMouse()方法)”的错误。原因在于,创建Cat对象时指向了Animal父类类型,这样新创建的Cat对象会自动向上转型为Animal类,然后通过父类对象an1分别调用了shout()方法和子类Cat特有的catchMouse()方法,而catchMouse()方法是Cat类特有的,所以通过父类对象调用时,在编译期间就会报错。
因此要解决上面的问题,可以将父类类型的对象an1强转为Cat类型。接下来对文件1中的main()方法进行修改,具体代码如下:
// 定义测试类
public class Example16 {
public static void main(String[] args) {
Animal an1 = new Cat();
Cat cat = (Cat) an1;
cat.shout();
cat.catchMouse();
}
}
Java提供了一个关键字instanceof,它可以判断一个对象是否为某个类(或接口)的实例或者子类实例,语法格式如下:
对象(或者对象引用变量) instanceof 类(或接口)
// 定义测试类
public class Example17 {
public static void main(String[] args) {
Animal an1 = new Dog();
if(an1 instanceof Cat){ // 判断an1本质类型
Cat cat = (Cat) an1;
cat.shout();
cat.catchMouse();
}else{
System.out.println("该类型的对象不是Cat类型!");
}
}
}
再次运行程序,结果如图4所示。
图4 运行结果
在对文件2修改的代码中,使用instanceof关键字判断对象an1本质是否为Cat类型,如果是Cat类型就强制转换为Cat类型,否则就打印“该类型的对象不是Cat类型!”。由于判断的对象an1本质为Dog类型并非Cat类型,因此出现图4的运行结果。