4.4.2 对象的类型转换

7 篇文章 0 订阅

将子类对象当做父类类型使用实现了多态的目标,这在Java中叫做向上转型,如下:

 Animal an1 = new Cat(); //创建Cat对象,通过Animal父类类型的变量an1引用子类类型的对象
 Animal an2 = new Dog(); //创建Dog对象,通过Animal父类类型的变量an2引用子类类型的对象

将子类对象当做父类使用时不需要任何显示地声明,但是,此时不能通过父类变量去调用子类中的特有方法。只能使用父类和子类所共有的方法,其实也就是父类有的方法。

如下为反面示例:

//定义接口Animal
 interface Animal {
     void shout();       //定义抽象shout方法
 }
 //定义Cat类实现Animal接口
 class Cat implements Animal {
     //实现shout方法
     public void shout(){
         System.out.println("喵喵...");
     }
     //定义sleep方法
     public void sleep(){
         System.out.println("猫在睡觉...");
     }
 }
 //定义向上转型测试类
 public class UpcastingWrong {
     public static void main(String[] args){
         Cat cat = new Cat();    //创建Cat类的实例对象
         animalShout(cat);       //调用animalShout()方法,将cat作为参数传入
     }
     //定义静态的animalShout()方法,接收一个Animal类型的参数
     public static void animalShout(Animal animal){
         animal.shout();             //调用实际参数的shout()方法
         animal.sleep();             //调用实际参数的sleep()方法
     }
 }

在上述代码的main方法中,调用animalShout()方法时,传入了Cat类型的对象,而方法的参数类型为Animal类型,这时将Cat对象当做父类Animal类型使用,也就是实现了向上转型

当编译器检查到代码的第25行时,发现Animal类中没有定义sleep方法,sleep方法只存在于Cat类中,而此时传入的对象已经向上转型当做Animal类型使用,所以找不到sleep方法。

此时会出现报错提示信息:The method sleep() is undefined for the type Animal Java(67108964)

但是此时由于传入的对象是Cat类型,Cat类型中定义了sleep()方法,所以我们可以通过类型转换来调用sleep()方法。

因此可以在animalShout()方法中将Animal类型的变量强制转换为Cat类型。将animalShout()方法代码修改如下:

 //定义静态的animalShout()方法,接收一个Animal类型的参数
     public static void animalShout(Animal animal){
         Cat cat = (Cat) animal;  //将animal对象强制转换为Cat类型并由Cat类型的cat引用
         cat.shout();             //调用实际参数的shout()方法
         cat.sleep();             //调用实际参数的sleep()方法
     }

修改后再次编译,即可正常运行。


如上这种将父类当做子类使用的情况,在Java中叫做向下转型,但是这种类型转换也有可能出现错误,比如当传入的对象和向下转型的对象不匹配时。

如下为反面示例:

//定义接口Animal
 interface Animal {
     void shout();       //定义抽象shout方法
 }
 //定义Cat类实现Animal接口
 class Cat implements Animal {
     //实现shout方法
     public void shout(){
         System.out.println("喵喵...");
     }
     //定义sleep方法
     public void sleep(){
         System.out.println("猫在睡觉...");
     }
 }
 //定义Dog类实现Animal接口
 class Dog implements Animal {
     //实现shout方法
     public void shout(){
         System.out.println("汪汪...");
     }
 }
 //定义向上转型测试类
 public class UpcastingWrong_2 {
     public static void main(String[] args){
         Dog dog = new Dog();    //创建Dog类的实例对象
         animalShout(dog);       //调用animalShout()方法,将dog作为参数传入
     }
     //定义静态的animalShout()方法,接收一个Animal类型的参数
     public static void animalShout(Animal animal){
         Cat cat = (Cat) animal;  //将animal对象强制转换为Cat类型并由Cat类型的cat引用
         cat.shout();             //调用实际参数的shout()方法
         cat.sleep();             //调用实际参数的sleep()方法
     }
 }
 ​

代码在运行时报错:Exception in thread "main" java.lang.ClassCastException: class Dog cannot be cast to class Cat (Dog and Cat are in unnamed module of loader 'app'

提示Dog类型不能转换为Cat类型,原因是,在调用animalShout()方法时,传入一个Dog对象,在强制类型转换向下转型时,Animal类型的变量无法强制转换为Cat类型。

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

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

接下来修改上面代码中的animalShout()方法如下:

    //定义静态的animalShout()方法,接收一个Animal类型的参数
     public static void animalShout(Animal animal){
         if (animal instanceof Cat){  //判断animal是否为Cat类的实例对象,如果是,则进行向下转换并调用两个方法
             Cat cat = (Cat) animal;  //将animal对象强制转换为Cat类型并由Cat类型的cat引用
             cat.shout();             //调用实际参数的shout()方法
             cat.sleep();             //调用实际参数的sleep()方法
         }else{
             System.out.println("This animal is not a Cat");
         }
     }

此时运行结果:This animal is not a Cat

说明instanceof判断animal不是Cat类的实例对象,运行else其后的内容。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值