java中的多态以及对象的类型转换

 多态

        多态指的就是同一事物在不同情况下表现出来的不同状态或者行为。在java中,当调用同一个方法时,由于对象存在差异,不同的对象之间可能存在不同的行为,当父类引用指向了子类对象,用这个父类引用调用子类中重写的方法时,多态就出现了。

        那么要如何理解多态的概念呢?这里说一个简单的例子,比如上班,将其理解为一个方法,这个方法在人这个类中有上班族这个对象来执行,但是不同的人的上班方式是不一样的,老板可能是开车上班的,打工人可能是挤地铁、坐公交或者骑共享单车上班的,还有可能是骑电瓶车上班的。这个对于同一个方法的不同实现方式就是指的多态,因此,在java中,多态只能是方法的多态,而不是属性的多态,多态与属性没有关系。

        需要注意的是,多态只能在拥有方法重写的子类与父类中出现,并且必须要有父类引用指向子类对象。那么又如何理解父类引用指向子类对象呢,这里先编写一个程序来实现多态,用实际的例子来说明父类引用指向子类对象。

        首先创建一个简单的Animal类,在这个类中定义一个shout方法,然后创建三个Animal类的子类,一个为Dog类,一个为Cat类,一个为Mouse类,在这前两个子类中重写shout方法,最后再定义一个测试类用来实现多态。以下为具体代码:

package cn.duotai.demo;import org.w3c.dom.ls.LSOutput;public class Animal {public void shout(){System.out.println("叫了一声!");}
}
class Dog extends Animal{public void shout(){System.out.println("汪汪汪!");}public void seeDoor(){System.out.println("看门!!");}}
class Cat extends Animal{public void shout(){System.out.println("喵喵喵!");}public void catchMouse(){System.out.println("抓老鼠!!");}
}
class Mouse extends Animal{public void shout() {System.out.println("叫了一声");}
}
package cn.duotai.demo;public class TestDuoTai {static void animalCry(Animal a){a.shout();}public static void main(String[] args) {Dog d = new Dog();animalCry(d);animalCry(new Cat());//测试类型转换Animal a= new Dog();//向上类型转换,自动类型转换//a.seeDoor();无法使用这种方式调用,编码事只能识别Animal,故调用时需要强制转型Dog d2 = (Dog)a;//强制转型,向下类型转换d2.seeDoor();//Cat c3 = (Cat)a;// c3.catchMouse();编译不会出错,但运行时会提示java.lang.ClassCastException:类型转换错误,狗不是猫if(a instanceof Dog){Dog d3 = (Dog)a;d3.seeDoor();}else if(a instanceof Cat){Cat cat = (Cat)a;cat.catchMouse();}}
}

        在以上的代码之中,有一行为 Animal a = new Dog();在这个代码之中,a 为父类Animal的引用,而a指向的是Dog类的对象,这就是一个很明显的父类引用指向子类对象的例子。那么Dog d = new Dog;animalCry;这两行代码中有没有涉及到父类引用指向子类对象呢?答案是有,这里要注意的是animalCry(Animal a )这个方法中传入的参数是Animal类,于是在执行 Dog d = new Dog;animalCry;这两行代码时就有一个隐含的赋值操作,这个操作为 Anamal a = d = new Dog. 很明显形式参数充当了Animal类的引用,这个引用指向了Dog类的对象。下面一行的Cat类代码也是同一个原理。

对象的类型转换

        在上面多态的例子中能够发现当实现父类的引用指向对象时,引用类型为Animal,而对象的类型为Dog。父类引用指向子类对象时,子类对象的类型应该要发生变化,变为Animal类的对象,也就是说,对象的类型能够发生转换。

        那么对象的类型转换要遵循什么样的规则呢?这里的规则和之前的数据类型转换时一样的,向上转换回自动转换,而向下转换则需要进行强制转换。比如Dog类的对象要转换为Animal类,由于Animal类是Dog类的父类,因此转换会自动进行,但是将父类Animal对象转换为Dog类的对象时就要强制转换了,就像以上代码中的Dog d3 = (Dog)a;一样。

        不过在这里要特别注意的一点是,同级别的对象之间能否相互转换呢?这里要说的是在编译上是允许的,但是在运行上是不允许的。也就是说,如果要进行同级别之间的对象转换,比如Dog类和Cat类都是Animal的直接子类,这时如果要将Dog类的对象强制转换为Cat类的对象,那么编译不会报错,但是运行时会报错,比如上面的代码中 //Cat c3 = (Cat)a; // c3.catchMouse();这两行在编译时时是不会报错的,但在运行时会提示对象不能进行强制转换。

        那么这是为什么呢?这里需要理解一句话:在java中进行类的对象转换时遵循编译看左,运行看右的原则。在上面的程序之中Animal a = new Dog();编译时,只看代码的左边,此时a 是Animal类,Animal类进行强转,满足Dog is Animal 的逻辑条件,自然能转为Cat类,因此不会报错,但是在运行时,看的是右边,此时a 为Dog类,Dog类和Cat类是同级的,Cat is Dog这个条件肯定不满足,因此程序执行错误,无法进行对象的类型转换。

        

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/782510.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深度学习十大算法之Diffusion扩散模型

1. 引言 扩散模型在近年来成为了热门话题,其火速蹿红主要归功于在图像生成领域的突破应用。尤其是一些从文本到图像的生成技术,它们成功地运用了扩散模型来创建令人惊叹的逼真图像。如果你听说过某个应用能够迅速且高质量地生成图像,那么很可…

【效率提升】Xinstall免填邀请码,让App注册更便捷

在移动互联网时代,App已经成为我们生活中不可或缺的一部分。然而,每当我们要尝试一个新的App时,繁琐的注册流程总是让人感到头疼。其中,填写邀请码这一环节更是让许多人望而却步。幸运的是,Xinstall作为国内专业的App全…

每日OJ题_栈⑤_力扣946. 验证栈序列

目录 力扣946. 验证栈序列 解析代码 力扣946. 验证栈序列 946. 验证栈序列 难度 中等 给定 pushed 和 popped 两个序列,每个序列中的 值都不重复,只有当它们可能是在最初空栈上进行的推入 push 和弹出 pop 操作序列的结果时,返回 true&a…

数据链路层之信道:数字通信的桥梁与守护者

✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…

C#/BS手麻系统源码 手术麻醉管理系统源码 商业项目源码

C#/BS手麻系统源码 手术麻醉管理系统源码 商业项目源码 手麻系统从麻醉医生实际工作环境和流程需求方面设计,与HIS,LIS,PACS,EMR无缝连接,方便查看患者的信息;实现术前、术中、术后手术麻醉信息全记录;减少麻醉医师在…

.NET Core教程:深入实践与实例解析

.NET Core教程:深入实践与实例解析 随着技术的发展,.NET Core作为微软推出的一个开源、跨平台的.NET实现,已经越来越受到开发者的青睐。本文将详细讲解.NET Core的基础知识,并通过实例来解析其关键特性和使用方法。 一、.NET Co…

AI程序员Devin的开源替代Devika

前天介绍了 AI软件工程师 微软AI 程序员AutoDev,自主执行工程任务生成代码-CSDN博客 今天介绍下另一款Devin替代品,开源的Devika (另外还有一个开源的 OpenDevin : https://github.com/OpenDevin/OpenDevin) Devika https://github.com/stitionai/dev…

Redis在多节点上如何实现分布式锁?

在多个 Redis 节点上实现分布式锁可以通过以下步骤来完成: 选择分布式锁的实现方式:有多种实现分布式锁的方式,如使用 Redis 的普通锁、RedLock 等。RedLock 是一种基于多个 Redis 节点的分布式锁实现,它通过在多个节点上获取锁来…

awesome-cheatsheets:超级速查表 - 编程语言、框架和开发工具的速查表

awesome-cheatsheets:超级速查表 - 编程语言、框架和开发工具的速查表,单个文件包含一切你需要知道的东西 官网:GitHub - skywind3000/awesome-cheatsheets: 超级速查表 - 编程语言、框架和开发工具的速查表,单个文件包含一切你需…

Python:魔法函数

注意:本文引用自专业人工智能社区Venus AI 更多AI知识请参考原站 ([www.aideeplearning.cn]) Python 的魔法函数,又称为特殊方法,是 Python 类中定义的一组特殊的方法,具有一些独特的特性和用途。这些方法…

今日总结2024/3/30

今日学习了基本数论内容,LCM,GCD以及筛素数 GCD-最大公约数 int gcd(int a,int b){//迭代法 while(b){//要保证a大于b int ta%b; ab; bt; } return a }//辗转相除法int gcd(int a,int b){//递归法return b?gcd(b,a%b):a;//一定要保证a大于b } LCM-最小公倍数 可以套公式LC…

解决WordPress文章的段落首行自动空两格的问题

写文章时,段落首行都会空两格,可是WordPress自带的编辑器却没有考虑到这一点,导致发布的文章首行都是顶格的,看起来很不习惯。 我们通常的解决方法都是在发布文章时把编辑器切换到“文本”模式,然后再在首行手动键入两…

鸿蒙之路由跳转router

router的使用都是基于Entry修饰的组件。 都是基于resources/base/profile/main-page.json中的路由配置来跳转的 router提供下列的几个方法 1.pushUrl -压栈一层盖一层(在鸿蒙中页面栈支持最大数值是32) 2.replaceUrl会替换当前页面,不管是不是同一个页面&#xf…

超声波雷达探测车位及信号处理方法

在APA泊车中用到了超声波雷达,第一次接触,总结研究之。 目录 1. 基于USS的泊车位识别及推荐1.1 基于AVM的泊车位识别1.2 障碍物识别2. 超声波雷达及车位探测信号处理1. 基于USS的泊车位识别及推荐 参考: F-APA车位搜索及障碍物识别控制原理 1.1 基于AVM的泊车位识别 (1)a…

P6学习:解析P6 WBS-工作分解结构的原则

前言 WBS,及Work Breakdown Structure,中文工作分解结构,是总结工作阶段的项目的层次结构分解。 WBS 就像项目的大纲——它将项目分解为特定的可交付成果或阶段。 然后将活动添加到这些层中以创建项目计划的时间表。 WBS 使用流程会有所不…

linux命令之tput

1.tput介绍 linux命令tput是可以在终端中进行文本和颜色的控制和格式化,其是一个非常有用的命令 2.tput用法 命令: man tput 3.样例 3.1.清除屏幕 命令: tput clear [rootelasticsearch ~]# tput clear [rootelasticsearch ~]# 3.2.…

love 2d Lua 俄罗斯方块超详细教程

源码已经更新在CSDN的码库里: git clone https://gitcode.com/funsion/love2d-game.git 一直在找Lua 能快速便捷实现图形界面的软件,找了一堆,终于发现love2d是小而美的原生lua图形界面实现的方式。 并参考相关教程做了一个更详细的&#x…

Https【Linux网络编程】

目录 一、为什么需要https 二、常见加密方法 1、对称加密 2、非对称加密 3、数据指纹 三、选择什么加密方案? 方案一:对称加密() 方案二:双方使用非对称加密(效率低) 方案三&#xff1a…

通过cplusplus网站学习函数用法演示

在我们学习c语言或者c时,总会遇到一些我们熟悉的库函数,这时候就需要我们通过cplusplus网站搜索学习,下面就由我为大家演示一下如何通过这个网站的页面学习函数的使用方法吧! atoi - C Reference (cplusplus.com) 我们今天要学习…

vue3全局控制Element plus所有组件的文字大小

项目框架vue-右上角有控制全文的文字大小 实现&#xff1a; 只能控制element组件的文字及输入框等大小变化&#xff0c;如果是自行添加div,text, span之类的控制不了。 配置流程 APP.vue 使用element的provide&#xff0c;包含app <el-config-provider :locale"loca…