一、对象转型介绍

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

1.1.对象转型实例一

  1 package javastudy.summary;2 3 /**4  * 父类Animal5  * @author gacl6  *7  */8 class Animal {9 10     public String name;11 12     public Animal(String name) {13         this.name = name;14     }15 }16 17 /**18  * 子类Cat继承Animal19  * @author gacl20  *21  */22 class Cat extends Animal {23 24     /**25      * Cat添加自己独有的属性26      */27     public String eyeColor;28 29     public Cat(String n, String c) {30         super(n);//调用父类Animal的构造方法31         this.eyeColor = c;32     }33 }34 35 /**36  * 子类Dog继承Animal37  * @author gacl38  *39  */40 class Dog extends Animal {41     /**42      * Dog类添加自己特有的属性43      */44     public String furColor;45 46     public Dog(String n, String c) {47         super(n);//调用父类Animal的构造方法48         this.furColor = c;49     }50 51 }52 53 /**54  * 下面是这三个类的测试程序55  * @author gacl56  *57  */58 public class TestClassCast {59 60     /**61      * @param args62      */63     public static void main(String[] args) {64 65         Animal a = new Animal("name");66         Cat c = new Cat("catname","blue");67         Dog d = new Dog("dogname", "black");68         /**69          * a instanceof Animal这句话的意思是a是一只动物吗?70          * a是Animal这个类里面的是一个实例对象,所以a当然是一只动物,其结果为true。71          */72         System.out.println(String.format("a instanceof Animal的结果是%s",a instanceof Animal));//true73         /**74          * c是Cat类的实例对象的引用,即c代表的就是这个实例对象,75          * 所以“c是一只动物”打印出来的结果也是true。76          * d也一样,所以“d是一只动物”打印出来的结果也是true。77          */78         System.out.println(String.format("c instanceof Animal的结果是%s",c instanceof Animal));//true79         System.out.println(String.format("d instanceof Animal的结果是%s",d instanceof Animal));//true80         /**81          * 这里判断说“动物是一只猫”,不符合逻辑,所以打印出来的结果是false。82          */83         System.out.println(String.format("a instanceof Cat的结果是%s",a instanceof Cat));84         /**85          * 这句话比较有意思了,a本身是Animal类的实例对象的引用,86          * 但现在这个引用不指向Animal类的实例对象了,而是指向了Dog这个类的一个实例对象了,87          * 这里也就是父类对象的引用指向了子类的一个实例对象。88          */89         a = new Dog("bigyellow", "yellow");90         System.out.println(a.name);//bigyellow91         /**92          * 这里的furColor属性是子类在继承父类的基础上新增加的一个属性,是父类没有的。93          * 因此这里使用父类的引用对象a去访问子类对象里面新增加的成员变量是不允许的,94          * 因为在编译器眼里,你a就是Animal类对象的一个引用对象,你只能去访问Animal类对象里面所具有的name属性,95          * 除了Animal类里面的属性可以访问以外,其它类里面的成员变量a都没办法访问。96          * 这里furColor属性是Dog类里面的属性,因此你一个Animal类的引用是无法去访问Dog类里面的成员变量的,97          * 尽管你a指向的是子类Dog的一个实例对象,但因为子类Dog从父类Animal继承下来,98          * 所以new出一个子类对象的时候,这个子类对象里面会包含有一个父类对象,99          * 因此这个a指向的正是这个子类对象里面的父类对象,因此尽管a是指向Dog类对象的一个引用,
100          * 但是在编译器眼里你a就是只是一个Animal类的引用对象,你a就是只能访问Animal类里面所具有的成员变量,
101          * 别的你都访问不了。
102          * 因此一个父类(基类)对象的引用是不可以访问其子类对象新增加的成员(属性和方法)的。
103          */
104         //System.out.println(a.furColor);
105         System.out.println(String.format("a指向了Dog,a instanceof Animal的结果是%s",a instanceof Animal));//true
106         /**
107          * 这里判断说“a是一只Dog”是true。
108          * 因为instanceof探索的是实际当中你整个对象到底是什么东西,
109          * 并不是根据你的引用把对象看出什么样来判断的。
110          */
111         System.out.println(String.format("a instanceof Dog的结果是%s",a instanceof Dog));//true
112         /**
113          * 这里使用强制转换,把指向Animal类的引用对象a转型成指向Dog类对象的引用,
114          * 这样转型后的引用对象d1就可以直接访问Dog类对象里面的新增的成员了。
115          */
116         Dog d1 = (Dog)a;
117         System.out.println(d1.furColor);//yellow
118     }
119
120 }

运行结果:

内存分析

  在内存中可以看到,指向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对象里面所有的成员了。

1.2.对象转型实例二

 1 public class TestClassCast {2 3     public void  f(Animal a) {4         System.out.println(a.name);5         if (a instanceof Cat) {6             Cat cat = (Cat)a;7             System.out.println(cat.eyeColor+" eye");8         }else if (a instanceof Dog) {9             Dog dog = (Dog)a;
10             System.out.println(dog.furColor+" fur");
11         }
12     }
13
14     /**
15      * @param args
16      */
17     public static void main(String[] args) {
18         Animal a = new Animal("name");
19         Cat c = new Cat("catname","blue");
20         Dog d = new Dog("dogname", "black");
21         TestClassCast testClassCast = new TestClassCast();
22         testClassCast.f(a);
23         testClassCast.f(c);
24         testClassCast.f(d);
25     }
26 }

  这里的这些代码是对前面声明的三个类Animal,Dog,Cat测试的延续,这里我们在TestClassCast这里类里面测试这个三个类,这里我们在TestClassCast类里面new了一个testClassCast对象,为的是调用TestClassCast类里面声明的f(Animal  a)这个方法,这个f()方法里面的参数类型是Animal类型,如果是Animal类型的参数,那么我们可以把这个Animal类型的子类对象作为参数传进去,这是可以的。如把一只Dog或者是一只Cat丢进f()方法里面这都是可以的,因为Dog和Cat也是Animal。因此当程序执行到testClassCast.f(a);,testClassCast.f(c);,testClassCast.f(d);的时候,因为f()方法里面的参数是Animal类型的,所以我们可以把一个Animal对象传进去,除此之外,我们还可以直接把从Animal类继承下来的Dog类和Cat类里面的Dog对象和Cat对象作为实参传递过去,即是把Animal类型的子类对象作为参数传进去。这里就体现出了继承和父类对象的引用可以指向子类对象的好处了,如果说没有继承关系的存在,如果说父类的引用不可以指向子类对象,那么我们就得要在Test类里面定义三个f()方法了,即要定义这样的f()方法:
f(Animal a)、f(Dog d)、f(Cat c)分别用来处理Animal、Dog和Cat,使用三个方法来处理,将来程序的扩展起来就不是很容易了,因为面向对象可以帮助我们这些年来编程苦苦追求的一个境界是可扩展性比较好。可扩展性比较好的一个典型例子就是说当你建好一个建筑之后或者是你写好这个程序之后,把这个主建筑给建好了,将来你要加一些其他的功能的时候,尽量不要去修改主结构,这叫可扩展性好,你盖了一座大楼,你现在要在大楼的旁边添加一个厨房,那你在它旁边一盖就行了,如果有人告诉你,我添加一个厨房我需要把你整个大楼的主要柱子都给拆了然后再盖一遍,这你干吗,肯定不干。如果结构设计成这样,那就是设计得不好,可扩展性不好。所以这里如果要把f()方法写成三个重载的f()方法,那么将来我输出一只鸟的时候又得要添加一个f(Bird  b)方法来处理鸟。这样扩展起来就太麻烦了,因为每处理一只动物都要添加一个新的方法,但是如果存在继承关系,如果父类对象的引用可以指向子类对象,那扩展起来就简单了,你可以把处理动物的方法写在一个方法f(Animal  a)里面就够了,因为所有动物的种类都是从Animal类继承下来,因此给f()方法传递Animal类型的参数的时候可以直接把这个Animal类的子类对象传进去,这样不管是要增加什么动物的输出,我都可以调用f(Animal a)方法去处理,这种扩展性比每次都要增加一个新的处理方法的扩展性要好得多,这就是继承的一个好处,这就是对象转型对于可扩展性来的好处:“对象的引用可以指向子类对象”,是因为面向对象的编程里面存在这样的继承关系,使得程序的可扩展性比较好。

  对象转型可以使父类对象的引用可以指向子类对象,给程序带来了比较好的可扩展性:我们可以在一个方法的参数里面定义父类的引用,然后实际当中传的时候传的是子类的对象,然后我们再在方法里面判断这个传过来的子类对象到底属于哪个子类,然后再去执行这个子类里面的方法或者调用这个子类里面的成员变量,因此程序的可扩展性比单独定义好多个方法要好一些。不过这个可扩展性还没有达到最好,使用多态就可以让程序的扩展性达到极致。

转载于:https://www.cnblogs.com/estellez/p/5625919.html

java基础—对象转型相关推荐

  1. 一天一个Java基础——对象和类

    1.在Java中你所做的全部工作就是定义类,产生那些类的对象,以及发送消息给这些对象 2.可以在类中设置两种类型的元素:字段(也被称作数据成员)和方法(也被称作成员函数) 3.字段可以是任何类型的对象 ...

  2. [Java基础]对象(反)序列化流

    对象序列化流: 代码如下: package ObjectOutputStreamPack;import java.io.Serializable;public class Student implem ...

  3. Java之对象转型(casting)

    1.一个基类的引用类型可以指向其子类的对象 2.一个基类的引用指向子类的对象时不可以访问其子类对象新增加的成员(属性和方法) 比如,一只狗继承动物类,如果将狗当成动物传入,那么狗局不能访问自己独有的成 ...

  4. Java基础- 对象相等判断

    hashCode equals == 对象相等判断 equals和==区别 hashCode 与 equals(重要) ※※ hashCode()介绍 hashCode()介绍(常见的几个问题) 为什 ...

  5. Java基础----对象与类

    一.面向对象程序设计概述 面向对象程序设计(oop) 二.类 类(class)是构造对象模板或蓝图 由类构造(construct)对象的过程称为创建类的实例(instance) 封装是处理对象的一个重 ...

  6. java基础---对象锁和类锁的区别

    synchronized 加到 static 方法前面是给class 加锁,即类锁:而synchronized 加到非静态方法前面是给对象上锁. 对象锁和类锁是不同的锁,所以多个线程同时执行这2个不同 ...

  7. 【零基础学Java】—对象的向上和向下转型(二十七)

    [零基础学Java]-对象的向上转型(二十七) 对象的向上转型,其实就是多态的写法 格式:父类名称 对象名=new 子类名称(): 含义:右侧创建一个子类对象,把它当做父类来看待使用 注意事项:向上转 ...

  8. 【JAVA基础知识总结】JAVA对象转型之上转型对象与下转型对象

    2019独角兽企业重金招聘Python工程师标准>>> JAVA对象转型分为两种:一种叫向下转型,而另一种是向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型) ...

  9. java基础学习总结——对象转型

    一.对象转型介绍 对象转型分为两种:一种叫向上转型(父类对象的引用或者叫基类对象的引用指向子类对象,这就是向上转型),另一种叫向下转型.转型的意思是:如把float类型转成int类型,把double类 ...

最新文章

  1. 任务调度器leetcode621
  2. 【keras】rnn中的LSTM
  3. 设计模式(3)-装扮你的类(装饰模式)
  4. 中psr_PSR-SX900测评:雅马哈升级幅度较大的高品质编曲键盘
  5. [图解tensorflow源码] [原创] Tensorflow 图解分析 (Session, Graph, Kernels, Devices)
  6. PS比狠大赛!看看谁家的照片更丑!
  7. 关于加域后win7、win8的C:\不能够新建文件,报0X0070522错误的解决方式
  8. 高通宣称其语音识别系统准确率高达95%
  9. 40个免费flash相册程序
  10. Atitit.nosql api 标准化 以及nosql数据库的实现模型分类差异
  11. 软件无线电实验 matlab,基于MATLAB和ModelSim的软件无线电课程实验设计
  12. python ev3图形化编程软件下载_【stm32图形化编程软件免费版下载】stm32图形化编程软件 v1.0 最新免费版-开心电玩...
  13. 学习笔记1——制作数据集
  14. 最新MQ与RabbitMQ面试题
  15. 腾达路由器dns服务器未响应,荣耀猎人游戏路由怎么设置
  16. c++ 统计英文文本中每个单词的词频并且按照词频对每行排序
  17. mysql删除某张表三个月前的数据
  18. 华为防火墙telnet配置
  19. (转)Unity MRTK语音输入
  20. python用牛顿迭代法求平方根_利用牛顿迭代法求平方根 - 业精于勤,荒于嬉;行成于思,毁于随! - OSCHINA - 中文开源技术交流社区...

热门文章

  1. Github图片无法打开的问题解决【2020.07.20更新】
  2. 通向财务自由之路02_成功的决定因素:你
  3. 如何选型商业智能和分析平台,Gartner给了这些建议!
  4. 设置手机项目首选参数
  5. eclipsevue代码怎么运行_打了多年的单片机调试断点到底应该怎么设置? | 颠覆认知...
  6. 可以多次使用同一个hbitmap吗_求婚钻戒和结婚钻戒可以是同一个吗?意义戴法各不同,别胡乱混淆...
  7. linux考试中的7654_全国计算机等级考试你了解多少?
  8. 数据结构 5-4-1 并查集
  9. STL常用函数总结-queue+priority_queue
  10. 动态规划——最长公共子序列