Java中的多态理解之向上转型和向下转型(一)

2023-11-06

多态

Java中的多态可以用一句话来概括:

父类引用指向子类对象

从这句话可以看出,有三个关键的点:
父类引用、指向关系、子类对象
在理解这句话之前,我们先来学习两个概念:向上转型和向下转型

注意:无论是向上转型还是向下转型,两个类之间都必须要有继承关系

向上转型

什么是向上转型呢,这里先用一段代码来演示一下:

class Test{
    public static void main(String[] args) {
          
        //向上转型
        Animal a = new Cat();
        a.move();
    }
}

public class Animal {

    public void move(){
        System.out.println("动物在移动");
    }
}

class Cat extends Animal{

    public void move(){
        System.out.println("猫咪在移动");
    }
}

这里,我们定义了一个Animal类,里面有一个move方法,还有一个Cat类,继承自Animal类,并且重写了Animal类的move方法,在主方法中,使用
new Cat()创建了一个Cat对象,但是在等号左边我们声明的类型却是Animal,这里就用到了向上转型。实际上这里的new Cat()创建出来的对象底层还是Cat类型,只不过这里我们用父类引用去指向了该对象。

因为Cat是继承自Animal类的,我们可以用 is a 的关系来描述 Cat和Animal,也就是Cat is a Animal,Cat类是子类,Animal是父类。像这种用父类的引用来指向子类对象的操作就称为向上转型

向下转型

从上面的向上转型我们可以得出结论,子类到父类的称为向上转型,那么父类到子类就称为向下转型
还是用一段代码来演示一下:

class Test{
    public static void main(String[] args) {

        Animal a = new Cat();
        a.move();
        
        //a.CatchMouse();
        Cat cat = (Cat)a;
        cat.CatchMouse();
    }
}

public class Animal {

    public void move(){
        System.out.println("动物在移动");
    }
}

class Cat extends Animal{

    public void move(){
        System.out.println("猫咪在移动");
    }

    public void CatchMouse(){
        System.out.println("猫咪可以抓老鼠");
    }
}

还是和上面代码类似,只不过这次在Cat类中添加了一个CatchMouse()方法。这个方法是Cat类独有的,我们通过父类引用a不能访问到。
这个时候就需要用到向下转型
首先,还是用刚才声明的a变量,只不过这一次我们需要在a变量前加上强制类型转换,也就是

Cat cat = (Cat)a;

这个括号中的Cat就是把刚才声明的父类引用转换成Cat对象。接下来就可以拿着转换后的对象,也就是cat对象去访问子类中的CatchMouse方法了。

总结:什么时候需要用到向下转型呢?

当我们想要访问子类中特有的方法的时候,就要用到向下转型(也叫强制类型转换)

但是,强制类型转换是有风险的
例如,下面这个代码:

	Animal animal = new Dog();
    Cat cat = (Cat)animal;
    cat.CatchMouse();

这里我们还采用父类引用指向子类对象的操作,将一个底层是Dog类型的对象向上转为Animal类型。然后我们将这个底层是Dog类型的对象转为Cat类型,编译的时候并不会报错。然后接下来去调用Cat类的特有方法CatchMouse,但是运行的时候却出现了 ClassCastException异常,也就是类型转换异常。

为什么会出现这个错误呢?
原因在于:
编译阶段,编译器检测到animal这个引用是Animal类型,而Animal和Cat之间存在继承关系,所以可以向下转型,这个时候编译器是可以通过的
运行阶段,堆内存实际创建的对象是:Dog对象。在实际运行过程中,拿着Dog对象转换成Cat对象就不行了。因为Dog和Cat之间没有继承关系

解决办法:使用 instanceof 关键字
当我们需要使用向上转型的时候,使用 instanceof关键字对类型先进行判断,然后再去执行相关语句,这样就保险了。

未完待续…

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中的多态理解之向上转型和向下转型(一) 的相关文章

随机推荐

  • Docker + ELK + SpringBoot部署

    步骤一 Docker安装ELK镜像 docker pull sebp elk 步骤二 启动镜像 方法一 Docker部署 docker run e ES JAVA OPTS Xms256m Xmx256m 设置虚拟机所需内存大小 p 560
  • 面试题:100个白球,100个黑球,每次取两个

    面试题 袋子里有黑白球各100个 每次从袋子里取2个球 若取的球颜色相同 则放入1个黑球 若不同 则放入1个白球 问 最后袋子里剩下1个黑球的概率是多少 思路一 每次取球有3种情况 1 两黑 此时放入1个黑球 黑球在袋子里个数为奇数个 白球
  • 网络原理详解(图文结合)

    目录 编辑一 应用层 1 请求和响应 2 通用的协议格式 1 xml 2 json 3 protobuffer 二 传输层 1 UDP 2 TCP 1 TCP 协议段格式 2 可靠传输的实现机制 确认应答机制 可靠性 超时重传机制 可靠性
  • VMware 安装 Windows11

    一 下载win11的镜像文件 可以在MSDN网站下载 MSDN系统库 致力于原版windows生态服务 二 创建虚拟机 1 双击打开VMware虚拟机 点击创建新的虚拟机 2 选择典型 推荐 然后点击下一步 3 在安装程序光盘映像文件下 点
  • 基于无法安装64位版本的visio,因为在您的PC上找到了以下32位程序的解决办法

    今天在给自己安装visio 64位版本的时候 出现 无法安装64位版本的visio 为在您的PC上找到了以下32位程序 microsoft access database engine 2010 english 请卸载所有32位Office
  • JAVA全排列算法

    利用java知识编写全排列算法 里面有我的个人理解注释 代码如下 package demo import java util ArrayList import java util Arrays import java util List S
  • 夺灵者哈卡(Hakkar, the Soulflayer)

    Hakkar the Soulflayer夺灵者哈卡Deathrattle Shuffle a Corrupted Blood into each player s deck 亡语 将一张 堕落之血 分别洗入双方玩家的牌库 Corrupte
  • java main()线程是不是最后一个退出的(相比较main中创建的其他多个线程)

    JVM会在所有的非守护线程 用户线程 执行完毕后退出 main线程是用户线程 仅有main线程一个用户线程执行完毕 不能决定JVM是否退出 也即是说main线程并不一定是最后一个退出的线程 public class MainThreadTe
  • 欧拉回路路径求解

    基本概念 今天讨论的主题是一类问题 就是欧拉路问题 有两种欧拉路 第一种叫做 Eulerian path trail 沿着这条路径走能够走遍图中每一条边 第二种叫做 Eularian cycle 沿着这条路径走 不仅能走遍图中每一条边 而且
  • 滑动平均滤波的Java实现

    滑动平均滤波的Java实现 滑动平均滤波是一种常用的信号处理技术 用于平滑输入信号并减少噪声的影响 本文将介绍如何使用Java实现滑动平均滤波 并提供相应的源代码 滑动平均滤波的原理是通过计算一系列连续输入信号的平均值来平滑信号 具体而言
  • el-calendar日历自定义显示内容

    版本信息 之前我整理了一篇VUE Element ui实战之el calendar日历自定义显示内容 有码友在评论区里分享了更简介的方式 看到后一直想尝试一下 所以本篇就是来 填坑的 按照提供的思路我尝试了一下 现将全部代码贴出来 以供大家
  • C/C++ cmake教程

    通过编写CMakeLists txt 然后运行cmake命令可以自动生成对应Makefile 从而控制make的编译过程 因此在学习cmake之前 建议先对make有个大致的了解 1 单个源文件的编译 如果你的项目只有一个源文件main c
  • 《一周搞定模电》-二极管

    一周搞定模电 二极管 提示 写完文章后 目录可以自动生成 如何生成可参考右边的帮助文档 文章目录 一周搞定模电 二极管 前言 一 什么是二极管 二 稳压二极管 整流二极管 开关二极管 前言 提示 这里可以添加本文要记录的大概内容 为找工作
  • 怎么排列html的顺序,css样式优先级及层叠的顺序排序探讨

    一般情况下 1位重要标志位 gt 4位特殊性标志 gt 声明先后顺序 important gt id gt class gt tag 使用 important可以改变优先级别为最高 其次是style对象 然后是id gt class gt
  • mysql:insert并发问题(on DUPLICATE KEY UPDATE)

    目录 一 insert 存在则更新 不存在则新增 1 表结构如下 2 sql语句 3 批量插入 某一条记录存在 则更新 其余进行新增 二 insert 存在则不进行任何操作 不存在则新增 1 sql语句 三 总结 小编最近在项目中 遇到了一
  • 你不知道的JavaScript---------语法

    目录 语句和表达式 语句的结果值 表达式的 副作用 上下文规则 标签语句 不推荐使用 代码块 对象结构 else if和可选代码块 在js中运算符有优先级 在js中的短路运算 函数参数 参数默认值 arguments 剩余参数 剩余参数和
  • 0基础小白入门SRC漏洞挖掘的正确姿势

    前言 有不少阅读过我文章的伙伴都知道 我从事网络安全行业已经好几年 积累了丰富的经验和技能 在这段时间里 我参与了多个实际项目的规划和实施 成功防范了各种网络攻击和漏洞利用 提高了安全防护水平 也有很多小伙伴私信问我怎么学 怎么挖漏洞 怎么
  • 安装mlxtend_python机器学习包mlxtend的安装和配置详解

    今天看到了mlxtend的包 看了下example集成得非常简洁 还有一个吸引我的地方是自带了一些data直接可以用 省去了自己造数据或者找数据的处理过程 所以决定安装体验一下 依赖环境 首先 sudo pip install mlxten
  • 若依图片上传到服务器,前端显示图片

    效果图如下 前端代码 table显示图片
  • Java中的多态理解之向上转型和向下转型(一)

    多态 Java中的多态可以用一句话来概括 父类引用指向子类对象 从这句话可以看出 有三个关键的点 父类引用 指向关系 子类对象 在理解这句话之前 我们先来学习两个概念 向上转型和向下转型 注意 无论是向上转型还是向下转型 两个类之间都必须要