对象的类型转换案例演示

在多态的学习中,涉及到将子类对象当做父类类型使用的情况,此种情况在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类特有的,所以通过父类对象调用时,在编译期间就会报错。

文件1中,由于通过“new Cat();”创建的对象本质就是Cat类型,所以通过Cat类型的对象调用catchMouse()方法是可行的,因此要解决上面的问题,可以将父类类型的对象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();
    }
}

修改后再次编译,程序没有报错,运行结果如图2所示。

图2 运行结果

从图2可以看出,将本质为Cat类型的an1对象由Animal类型向下转型为Cat类型后,程序可以成功运行。需要注意的是,在进行对象向下类型转换时,必须转换为本质类型,否则转换时会出现错误,假如文件4-16中Animal类型引用指向的是一个Dog类型对象,这时进行强制类型转换为Cat类时就会出现出错,如文件2所示。

文件2 Example17.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("小猫抓老鼠……");
         }
     }
     // 定义Dog类实现Animal接口
     class Dog implements Animal {
         // 实现接口shout()方法
         public void shout() {
             System.out.println("汪汪……");
         }
     }
     // 定义测试类
     public class Example17 {
         public static void main(String[] args) {
             Animal an1 = new Dog(); 
             Cat cat = (Cat) an1;
             cat.shout();
             cat.catchMouse();
         }
     }

运行结果如图3所示。

图3 运行结果

文件2编译正常,但在运行时就会报错,提示Dog类型不能转换成Cat类型。出错的原因是,创建的Animal对象本质是一个Dog对象,在强制类型转换时,Dog类型的对象显然无法强转为Cat类型。

为了避免上述这种异常情况的发生,Java提供了一个关键字instanceof,它可以判断一个对象是否为某个类(或接口)的实例或者子类实例,语法格式如下:

对象(或者对象引用变量) instanceof 类(或接口)

接下来对文件2的测试类Example17进行修改,具体代码如下:

// 定义测试类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的运行结果。

猜你喜欢:

什么是多态?多态是怎样运行的?

类的加载机制是什么?【Java面试题】

servlet的生命周期及servlet常用方法

传智教育java开发培训课程

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/253935.html

(0)
上一篇 2022年5月9日
下一篇 2022年5月9日

相关推荐

发表回复

登录后才能评论