261、Java基础38 - 接口与继承【对象转型】 2019.11.18
0、目录
- 1、明确引用类型与对象类型的概念
- 2、子类转父类(向上转型)
- 3、父类转子类(向下转型)
- 4、没有继承关系的两个类,互相转换
- 5、实现类转换成接口(向上转型)
- 6、接口转换成实现类(向下转型)
- 7、instanceof
- 8、练习:类型转换
- 9、参考链接
1、明确引用类型与对象类型的概念
首先,明确引用类型与对象类型的概念
在这个例子里,有一个对象 new ADHero(), 同时也有一个引用ad
对象是有类型的, 是ADHero
引用也是有类型的,是ADHero
通常情况下,引用类型和对象类型是一样的
接下来要讨论的类型转换的问题,指的是引用类型和对象类型不一致的情况下的转换问题
package charactor;public class Hero {public String name;protected float hp;public static void main(String[] args) {ADHero ad = new ADHero();}
}
2、子类转父类(向上转型)
所谓的转型,是指当引用类型和对象类型不一致的时候,才需要进行类型转换
类型转换有时候会成功,有时候会失败(参考基本类型的类型转换)
到底能否转换成功? 教大家一个很简单的判别办法
把右边的当做左边来用,看说得通不
Hero h = new Hero();
ADHero ad = new ADHero();
h = ad;
右边ad引用所指向的对象的类型是 物理攻击英雄
左边h引用的类型是 普通英雄
把物理攻击英雄 当做 普通英雄,说不说得通? 说得通,就可以转
所有的子类转换为父类,都是说得通的。比如你身边的例子
苹果手机 继承了 手机,把苹果手机当做普通手机使用
怡宝纯净水 继承了 饮品, 把怡宝纯净水 当做饮品来使用
package charactor;public class Hero {public String name;protected float hp;public static void main(String[] args) {Hero h = new Hero();ADHero ad = new ADHero();//类型转换指的是把一个引用所指向的对象的类型,转换为另一个引用的类型//把ad引用所指向的对象的类型是ADHero//h引用的类型是Hero//把ADHero当做Hero使用,一定可以h = ad;}
}
3、父类转子类(向下转型)
- 父类转子类,有的时候行,有的时候不行,所以必须进行强制转换。
- 强制转换的意思就是 转换有风险,风险自担。
什么时候行呢?
Hero h =new Hero();
ADHero ad = new ADHero();
h = ad;
ad = (ADHero) h;
第3行,是子类转父类,一定可以的
第4行,就是父类转子类,所以要进行强转。
h这个引用,所指向的对象是ADHero, 所以第4行,就会把ADHero转换为ADHero,就能转换成功。
什么时候转换不行呢?
Hero h =new Hero();
ADHero ad = new ADHero();
Support s =new Support();
h = s;
ad = (ADHero)h;
第4行,是子类转父类,是可以转换成功的
第5行,是把h引用所指向的对象 Support,转换为ad引用的类型ADHero。 从语义上讲,把物理攻击英雄,当成辅助英雄来用,说不通,所以会强制转换失败,并且抛出异常
以下是对完整的代码的关键行分析
14行: 把ad当做Hero使用,一定可以
转换之后,h引用指向一个ad对象
15行: h引用有可能指向一个ad对象,也有可能指向一个support对象
所以把h引用转换成AD类型的时候,就有可能成功,有可能失败
因此要进行强制转换,换句话说转换后果自负
到底能不能转换成功,要看引用h到底指向的是哪种对象
在这个例子里,h指向的是一个ad对象,所以转换成ADHero类型,是可以的
16行:把一个support对象当做Hero使用,一定可以
转换之后,h引用指向一个support对象
17行:这个时候,h指向的是一个support对象,所以转换成ADHero类型,会失败。
失败的表现形式是抛出异常 ClassCastException 类型转换异常
package charactor;import charactor1.Support;public class Hero {public String name;protected float hp;public static void main(String[] args) {Hero h =new Hero();ADHero ad = new ADHero();Support s =new Support();h = ad;ad = (ADHero) h;h = s;ad = (ADHero)h;}}
4、没有继承关系的两个类,互相转换
没有继承关系的两个类,互相转换,一定会失败
虽然ADHero和APHero都继承了Hero,但是彼此没有互相继承关系
“把魔法英雄当做物理英雄来用”,在语义上也是说不通的
package charactor;public class Hero {public String name;protected float hp;public static void main(String[] args) {ADHero ad = new ADHero();APHero ap = new APHero();// 没有继承关系的类型进行互相转换一定会失败,所以会出现编译错误ad = (ADHero) ap;}}
5、实现类转换成接口(向上转型)
引用ad指向的对象是ADHero类型,这个类型实现了AD接口
10行: 把一个ADHero类型转换为AD接口
从语义上来讲,把一个ADHero当做AD来使用,而AD接口只有一个physicAttack方法,这就意味着转换后就有可能要调用physicAttack方法,而ADHero一定是有physicAttack方法的,所以转换是能成功的。
package charactor;public class Hero {public String name;protected float hp;public static void main(String[] args) {ADHero ad = new ADHero();AD adi = ad;}}
6、接口转换成实现类(向下转型)
10行: ad引用指向ADHero, 而adi引用是接口类型:AD,实现类转换为接口,是向上转型,所以无需强制转换,并且一定能成功
12行: adi实际上是指向一个ADHero的,所以能够转换成功
14行: adi引用所指向的对象是一个ADHero,要转换为ADAPHero就会失败。
假设能够转换成功,那么就可以使用magicAttack方法,而adi引用所指向的对象ADHero是没有magicAttack方法的。
package charactor;public class Hero {public String name;protected float hp;public static void main(String[] args) {ADHero ad = new ADHero();AD adi = ad;ADHero adHero = (ADHero) adi;ADAPHero adapHero = (ADAPHero) adi;adapHero.magicAttack();}}
7、instanceof
instanceof Hero 判断一个引用所指向的对象,是否是Hero类型,或者Hero的子类
package charactor;public class Hero {public String name;protected float hp;public static void main(String[] args) {ADHero ad = new ADHero();APHero ap = new APHero();Hero h1= ad;Hero h2= ap;//判断引用h1指向的对象,是否是ADHero类型System.out.println(h1 instanceof ADHero);//判断引用h2指向的对象,是否是APHero类型System.out.println(h2 instanceof APHero);//判断引用h1指向的对象,是否是Hero的子类型System.out.println(h1 instanceof Hero);}
}
8、练习:类型转换
如下转换能否成功?
如果不能,是哪一行会出错?
为什么会出错
package charactor;public class Hero {public String name;protected float hp;public static void main(String[] args) {ADHero ad = new ADHero();Hero h = ad;AD adi = (AD) h;APHero ap = (APHero) adi;}
}// 解答:
// Hero h = ad 这一行是没错 是由子转父,
// AD adi = (AD) h; 这一行是因为h指向ADHero,强行转为AD也是可行的,最后达到父转子
// APHero ap = (APHero) adi; 这个adi是指向AD的,不能强行转向APhero,所以这里有问题
9、参考链接
[01] How2j - 接口与继承系列教材 (二)- JAVA中的对象转型
261、Java基础38 - 接口与继承【对象转型】 2019.11.18相关推荐
- JAVA基础之接口与继承
在设计LOL的时候,进攻类英雄有两种,一种是进行物理系攻击,一种是进行魔法系攻击 这时候,就可以使用接口来实现这个效果. 接口就像是一种约定,我们约定某些英雄是物理系英雄,那么他们就一定能够进行物理攻 ...
- JAVA基础学习-接口与继承
8.1 接口 在设计LOL的时候,进攻类英雄有两种,一种是进行物理系攻击,一种是进行魔法系攻击 这时候,就可以使用接口来实现这个效果. 接口就像是一种约定,我们约定某些英雄是物理系英雄,那么他们就一定 ...
- Java基础-面向接口(interface)编程
Java基础-面向接口(interface)编程 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.接口的概念 接口是功能的集合,同样可看做是一种数据类型,是比抽象类更为抽象的&q ...
- Java中实现接口与继承的区别
** Java中实现接口与继承的区别 ** 首先,先来了解一下什么是接口和继承.接口一般是使用interface来定义的.接口定义同类的定义类似,分为接口的声明和接口体,其中接口体由常量定义和方法定义 ...
- Java基础知识运用,用对象,线程,Java窗口画出太阳系
一个项目让你搞懂对象:Java基础知识运用,用对象,线程,GUI画出太阳系 一.需求分析: 用java基础知识画出太阳系八大行星的运行轨迹图,要求:运行轨迹图是动态图片,画出运行轨迹,画出地月系(不需 ...
- (31)Java基础语法 --接口
目录 1.接口的概述 2.接口的定义格式 3.在接口中定义抽象方法 4.定义接口的 实现类 5.接口的使用 接口练习 6.接口的特点 7.一个实现类可以同时实现多个接口 8.接口的继承 9.设计提示 ...
- Java基础知识之封装+继承+多态详解
前言 这篇博客是基于Java类和对象的基础之上的相关知识点.因为特别重要且语法规则较多,所以想单独总结方便之后复习. 本篇博客涉及知识点思维导图: 目录 1.封装 2.继承 3.多态 1.封装 生活中 ...
- 大数据 -- java基础8 接口特点和用法
1.接口:interface关键字 (1)语句定义格式: interface 接口名{} (2)接口是如何实现的呢? 接口不能直接实例化,需要一个关键字供其他类实现该接口:im ...
- Java基础系列三之继承
继承 一.什么是继承 继承是一个类继承另一个类,这个类拥有被继承的类中所有的成员方法(除了父类的构造方法)和属性: 继承是面向对象特征之一: 实现继承的类称为子类或者派生类,被继承的类称为父类,或者称 ...
最新文章
- iactionresult 图片_从显式类型的ASP.NET Core API控制器(不是IActionResult)返回404
- php 请求服务器时间设置,学习猿地-php如何设置服务器时间
- 哪些医药企业使用SAP系统呢?
- C语言如何在可变参数函数中使用printf?
- python语言属于哪一种语言_Python与Java:你应该学习哪种语言,他们有什么区别?...
- Flink Kafka consumer的消费策略配置
- css定位,的重新理解,仔细理解描述即可
- linux修改服务器时间_操作系统基础解析:Windows和Linux 到底有何不同?
- php取数组里面数组的值,PHP获取数组的键与值方法小结
- 指针学习4--合成析构函数做了什么
- forward内部跳转 和redirect重定向跳转的区别
- java pipeline 实现_Docker+Jenkins+Pipeline实现持续集成(二)java项目构建
- java 示例_Java最终关键字示例
- 操作系统期末复习【超实用】
- 2008年金融危机的背后原因以及感悟
- python 怕网页_如何像玩游戏一样学Python?
- mysql连接navicat premium 15的具体方法 附navicat的官网连接
- yolov5方框的颜色及粗细更改
- Qt Design Studio 2.2 测试版发布啦!迎来全新属性视图
- 基于容器的后端服务架构