对象转型(向上转型和向下转型)

一、对象转型介绍


对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型。转型的意思是:如把float类型转成int类型,把double类型转成float类型,把long类型转成int类型,这些都叫转型。把一种形式转成另外一种形式就叫转型。除了基础数据类型的转型之外(基础数据类型的转型:大的可以转成小的,小的也可以转成大的。),对象领域里面也有对象之间的转型。

1.1.对象转型实例一



 public class TestClassCast {

      public static void main(String[] args) {
 
         Animal a = new Animal("name");
         Cat c = new Cat("catname","blue");

        /**
         * a instanceof Animal这句话的意思是a是一只动物吗?
         * a是Animal这个类里面的是一个实例对象,所以a当然是一只动物,其结果为true。
         */
         System.out.println(String.format("a instanceof Animal的结果是%s",a instanceof Animal));//true
 
         /**
          * 这里判断说“动物是一只猫”,不符合逻辑,所以打印出来的结果是false。
         */
        System.out.println(String.format("a instanceof Cat的结果是%s",a instanceof Cat));
        /**
          * 这句话比较有意思了,a本身是Animal类的实例对象的引用,
         * 但现在这个引用不指向Animal类的实例对象了,而是指向了Dog这个类的一个实例对象了,
          * 这里也就是父类对象的引用指向了子类的一个实例对象。
         */
         a = new Dog("bigyellow", "yellow");
         System.out.println(a.name);//bigyellow
         /**
          * 这里的furColor属性是子类在继承父类的基础上新增加的一个属性,是父类没有的。
          * 因此这里使用父类的引用对象a去访问子类对象里面新增加的成员变量是不允许的,
          * 因为在编译器眼里,你a就是Animal类对象的一个引用对象,你只能去访问Animal类对象里面所具有的name属性,
          * 除了Animal类里面的属性可以访问以外,其它类里面的成员变量a都没办法访问。
          * 这里furColor属性是Dog类里面的属性,因此你一个Animal类的引用是无法去访问Dog类里面的成员变量的,
          * 尽管a指向的是子类Dog的一个实例对象,但因为子类Dog从父类Animal继承下来,
          * 所以new出一个子类对象的时候,这个子类对象里面会包含有一个父类对象,
          * 因此这个a指向的正是这个子类对象里面的父类对象,因此尽管a是指向Dog类对象的一个引用
          * 但是在编译器眼里你a就是只是一个Animal类的引用对象,你a就是只能访问Animal类里面所具有的成员变量,
          * 别的你都访问不了。
          * 因此一个父类(基类)对象的引用是不可以访问其子类对象新增加的成员(属性和方法)的。
         */
        
         //System.out.println(a.furColor);
         System.out.println(String.format("a指向了Dog,a instanceof Animal的结果是%s",a instanceof Animal));//true
         /**
         * 这里判断说“a是一只Dog”是true。
         * 因为instanceof探索的是实际当中你整个对象到底是什么东西,
         * 并不是根据你的引用把对象看出什么样来判断的。

          */
         System.out.println(String.format("a instanceof Dog的结果是%s",a instanceof Dog));//true
        
         /**
         * 这里使用强制转换,把指向Animal类的引用对象a转型成指向Dog类对象的引用,
          * 这样转型后的引用对象d1就可以直接访问Dog类对象里面的新增的成员了。

         */
         Dog d1 = (Dog)a;
         System.out.println(d1.furColor);//yellow
    }

 }


内存分析


   在内存中可以看到,指向Dog类实例对象的引用对象a是一个Animal类型的引用类型,这就比较有意思了,Animal类型指向了Dog这个对象,那么,在程序的眼睛里会把这只Dog当成一只普通的Animal,既然是把Dog当成一只普通的Animal,那么Dog类里面声明的成员变量furColor就不能访问了,因为Animal类里面没有这个成员变量。因此,从严格意义上来讲,这个a眼里只看到了这个子类对象里面的父类对象Animal,因此能访问得到的也只是这个Animal对象里面的name属性,而这个Animal对象外面的furColor属性是访问不到的,虽然Dog对象确实有这个属性存在,但a就是看不到,a门缝里看Dog——把Dog看扁了,不知道Dog还有furColor这个属性存在,因此a访问不了furColor属性,因此从严格意义上来讲,a指向的只是这个Dog对象里面的Animal对象,也就是黄色箭头指向的那部分,a就只看到了Dog里面这部分,而Dog外面的部分都看不到了。这就是父类引用指向子类对象,父类引用指向子类对象的时候,它看到的只是作为父类的那部分所拥有的属性和方法,至于作为子类的那部分它没有看到。

  如果真的想访问Dog对象的furColor属性,那就采用对象转型的办法,把父类对象的引用转型成子类对象的引用。Dog d1 = (Dog)a;这里采用的就是对象转型的办法,把a强制转换成一只Dog对象的引用,然后将这个引用赋值给Dog型的引用变量d1,这样d1和a都是指向堆内存里面的Dog对象了,而且d1指向的就是这只Dog所有的部分了,通过这个d1就可以访问Dog对象里面所有的成员了。


  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KunQian_smile

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值