当前位置: 首页 > news >正文

Java中的 向上转型 | 向下转型

目录

一.向上转型

直接赋值 

总结:

通过传参

通过返回值

二.向下转型

instanceof 


一.向上转型

向上转型其实就是创建一个子类对象,并将其当作父类对象来使用,一般语法格式如下:

父类类型 对象名 = new 子类类型()

一般有以下三种使用场景:

直接赋值 

我们这里以父类为Animal类举例,并且有一个Cat类来继承他 

class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name = name;this.age = age;}public void eat() {System.out.println(this.name + "正在吃食物~~~");}
}
class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);}
}

        在这种情况下,我们用父类对象直接引用子类对象,不但程序不会报错,反而还可以正常调用父类中的成员方法

    public static void main(String[] args) {Cat cat = new Cat("布偶",3);Animal animal1 = cat;animal1.eat();Animal animal2 = new Cat("橘猫",2);animal2.eat();}

输出结果: 

那能不能调用子类的成员方法呢?我们在子类中新添加一个sleep方法

class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name = name;this.age = age;}public void eat() {System.out.println(this.name + "正在吃食物~~~");}
}
class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);}//新添加的子类方法public void sleep() {System.out.println(this.name + "正在睡觉......");}
}

我们尝试用上述过程来调用以下子类的中的方法:

    public static void main(String[] args) {       Animal animal = new Cat("橘猫",2);animal.eat();animal.sleep();   }

但是等我们写好了后,就会发现编译器报错了 

也就是说:

使用向上转型后,我们可以正常调用父类中的成员方法,但是不能调用子类中自己的方法

但是要解决上述问题还是很简单的,当我们在子类中重写父类方法后,我们就可以调用子类方法了,这也就是我们多态的实现

class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name = name;this.age = age;}public void eat() {System.out.println(this.name + "正在吃食物~~~");}public void sleep() {}
}
class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);}public void sleep() {System.out.println(this.name + "正在睡觉......");}
}
    public static void main(String[] args) {Animal animal = new Cat("橘猫",2);animal.eat();animal.sleep();}

现在我们就可以正常调用输出了:

总结:

当我们通过向上转型新建了一个对象后,我们可以通过这个对象来访问父类中的方法,但是不能访问子类中自己的方法,除非我们在子类中重写父类方法,也就是说当一个方法只有在父类和子类中都出现的情况下,我们才能访问子类中的这个方法

通过向上转型新建的对象可以访问的方法范围是:

  • 父类有 子类没有
  • 父类有 子类也有 

不能访问的范围是

  • 父类没有 子类也没有
  • 父类没有 但子类有 

通过传参

class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name = name;this.age = age;}public void eat() {System.out.println(this.name + "正在吃食物~~~");}
}
class Dog extends Animal {//构造方法public Dog(String name,int age) {super(name,age);}public void eat(){System.out.println(this.name + "正在吃狗粮~~~");}
}
class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);}public void eat(){System.out.println(this.name + "正在吃猫粮~~~");}
}
    public static void fun(Animal animal) {animal.eat();}
fun(new Dog("哈士奇",2));
fun(new Cat("橘猫",2));

 我们通过一个方法来接受一个父类对象,然后通过这个父类对象来调用eat方法,当我们传入的参数是一个子类对象的时候,就相当于我们用父类对象做参数来接到了子类对象,也就是发生了向上转型

输出结果:

通过返回值

class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name = name;this.age = age;}public void eat() {System.out.println(this.name + "正在吃食物~~~");}
}
class Dog extends Animal {//构造方法public Dog(String name,int age) {super(name,age);}public void eat(){System.out.println(this.name + "正在吃狗粮~~~");}
}
class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);}public void eat(){System.out.println(this.name + "正在吃猫粮~~~");}
}
    public static Animal fun1(Animal animal) {return new Cat("布偶",3);}public static Animal fun2(Animal animal) {return new Dog("哈士奇",2);}

我们用父类对象做返回值类型,但是我们返回的是子类对象,这也就相当于发生了向上转型

向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法 

二.向下转型

将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转换

 

class Animal {String name;int age;//构造方法public Animal(String name,int age) {this.name = name;this.age = age;}public void eat() {System.out.println(this.name + "正在吃食物~~~");}public void sleep() {}
}
class Cat extends Animal {//构造方法public Cat(String name,int age) {super(name,age);}public void sleep() {System.out.println(this.name + "正在睡觉......");}
}
public class Test_4 {public static void main(String[] args) {Animal animal = new Cat("橘猫",2);Cat cat = new Cat("布偶",2);animal.eat();animal.sleep();cat = (Cat)animal;cat.eat();cat.sleep();}
}

 输出结果:

instanceof 

向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。Java中为了提高向下转型的安全性,引入了 instanceof  ,如果该表达式为true,则可以安全转换 

public static void main(String[] args) {Cat cat = new Cat("元宝",2);Dog dog = new Dog("小七", 1);// 向上转型Animal animal = cat;animal.eat();animal = dog;animal.eat();if(animal instanceof Cat) {cat = (Cat)animal;}if(animal instanceof Dog) {dog = (Dog)animal;}
}

对于instanceof的详细信息可以查看官方资料:

 Chapter 15. Expressions (oracle.com)

 




相关文章:

Java中的 向上转型 | 向下转型

目录 一.向上转型 直接赋值 总结: 通过传参 通过返回值 二.向下转型 instanceof 一.向上转型 向上转型其实就是创建一个子类对象,并将其当作父类对象来使用,一般语法格式如下: 父类类型 对象名 new 子类类型() 一般有以…...

【华为OD机试AB高分必刷题目】朋友圈(C++-并查集Union-Find实现)

🚀你的旅程将在这里启航!本专栏所有题目均包含优质解题思路,高质量解题代码,详细代码讲解,助你深入学习,高分通过! 文章目录 【华为OD机试AB高分必刷题目】朋友圈(C++-并查集Union-Find实现)题目描述解题思路C++题解代码代码OJ评判结果代码讲解寄语【华为OD机试AB高分…...

前端面试题之vue篇

vue基础 vue的基本原理 当一个Vue实例创建时,Vue会遍历data中的属性,用Object.defineProperty(Vue使用proxy)转换为getter/setter,并且在内部追踪相关依赖,在属性被访问和修改时通知变化。每个组件实例都有相应的watcher程序实例…...

Java进阶(垃圾回收GC)——理论篇:JVM内存模型 垃圾回收定位清除算法 JVM中的垃圾回收器

前言 JVM作为Java进阶的知识,是需要Java程序员不断深度和理解的。 本篇博客介绍JVM的内存模型,对比了1.7和1.8的内存模型的变化;介绍了垃圾回收的语言发展;阐述了定位垃圾的方法,引用计数法和可达性分析发以及垃圾清…...

GaN HEMT 电容的分析建模,包括寄生元件

标题:Analytical Modeling of Capacitances for GaN HEMTs, Including Parasitic Components 来源:IEEE TRANSACTIONS ON ELECTRON DEVICES(14年) 摘要:本文提出了一种基于表面势的终端电荷和电容模型,包…...

Python实战 | 使用 Python 和 TensorFlow 构建卷积神经网络(CNN)进行人脸识别

专栏集锦,大佬们可以收藏以备不时之需 Spring Cloud实战专栏:https://blog.csdn.net/superdangbo/category_9270827.html Python 实战专栏:https://blog.csdn.net/superdangbo/category_9271194.html Logback 详解专栏:https:/…...

JLink edu mini 10Pin接口定义

注意:SWD接口在阵脚2,4;而20Pin的SWD接口在阵脚7,9 参考:1 官网资料; 2 【润石RS0104YQ Demo开发板测试分享】J-Link EDU Mini调试5V系统_国产运算放大器_模拟开关_线性稳压器_电平转换器_小逻辑_比较器…...

compile: version “go1.19“ does not match go tool version “go1.18.1“

** 1 安装了新版本的go后 为什么go version 还是旧版本? ** 如果你已经按照上述步骤安装了新版本的 Go,但 go version 命令仍然显示旧版本,可能是因为你的环境变量设置不正确或未正确生效。你可以尝试以下方法来解决问题: 重新…...

spring boot security 自定义AuthenticationProvider

spring boot security 自定义AuthenticationProvider 基于 spring boot 3.x 场景实现 手机验证码登陆 实现 CaptureCodeAuthenticationFilter public class CaptureCodeAuthenticationFilter extends AbstractAuthenticationProcessingFilter {private static final Strin…...

某电力设计公司绩效考核优化项目成功案例纪实

——引入角色定位考核法,建立多维度评价体系,支持业务转型后的客观评价 【客户行业】电力行业 【问题类型】绩效考核 【客户背景及现状分析】 某电力设计公司成立于2000年左右,是一家从事输变电工程勘察、设计、咨询的专业公司&#xff0c…...

力扣371周赛

力扣第371场周赛 找出强数对的最大异或值 I 枚举 class Solution { public:int maximumStrongPairXor(vector<int>& a) {int n a.size() , res 0;for(int i 0 ; i < n ; i ){for(int j 0 ; j < n ; j ){if(abs(a[i]-a[j])<min(a[i],a[j])){int c (a…...

Python之字符串、正则表达式练习

目录 1、输出随机字符串2、货币的转换&#xff08;字符串 crr107&#xff09;3、凯撒加密&#xff08;book 实验 19&#xff09;4、字符替换5、检测字母或数字6、纠正字母7、输出英文中所有长度为3个字母的单词 1、输出随机字符串 编写程序&#xff0c;输出由英文字母大小写或…...

Transmit :macOS 好用的 Ftp/SFtp 工具

Transmit 是一种功能强大的 FTP/SFTP/WebDAV 客户端软件&#xff0c;是一个 Mac OS X 平台上设计的文件传输软件。它由 Panic&#xff08;一家以软件工具为主的公司&#xff09;开发和维护&#xff0c;是一款非常受欢迎且易于使用的软件&#xff0c;而且被广泛认为是 Mac OS X …...

【Github】git clone命令下载文件中途停止

方法一&#xff1a; 使用git clone命令下载github上的源代码时&#xff0c;有时文件下载到一定百分比时就停止不动&#xff0c; 这是因为我们所下载的文件很大&#xff0c;超过了git预先分配的Postbuffer容量&#xff0c;所以一直卡在那里。可以使用以下命令查看当前Postbuffe…...

Clickhouse学习笔记(10)—— 查询优化

单表查询 Prewhere 替代 where prewhere与where相比&#xff0c;在过滤数据的时候会首先读取指定的列数据&#xff0c;来判断数据过滤&#xff0c;等待数据过滤之后再读取 select 声明的列字段来补全其余属性 简单来说就是先过滤再查询&#xff0c;而where过滤是先查询出对应…...

[量化投资-学习笔记012]Python+TDengine从零开始搭建量化分析平台-策略回测

上一章节《MACD金死叉策略回测》中&#xff0c;对平安银行这只股票&#xff0c;按照金死叉策略进行了回测。 但通常我们的股票池中有许多股票&#xff0c;每完成一个交易策略都需要对整个股票池进行回测。 下面使用简单的轮询&#xff0c;对整个股票池进行回测。 # 计算单只…...

MySQL 查看 event 执行记录

文章目录 1. 查看 EVENT 执行记录2. 示例3. 结论 MySQL 是一款流行的关系型数据库管理系统&#xff0c;它提供了许多功能来帮助用户管理和操作数据库。其中之一就是 EVENT事件&#xff0c;它允许用户在特定的时间间隔内自动执行指定的操作&#xff0c;类似于计划任务。 在使用 …...

开发知识点-Vue-Electron

Electron ElectronVue打包.exe桌面程序 ElectronVue打包.exe桌面程序 为了不报错 卸载以前的脚手架 npm uninstall -g vue-cli安装最新版脚手架 cnpm install -g vue/cli创建一个 vue 随便起个名 vue create electron-vue-example (随便起个名字electron-vue-example)进入 创建…...

【线性代数】反求矩阵A

...

MyBatis 中的 foreach 的用法

本文将介绍 MyBatis 中的 <foreach> 标签的灵活应用&#xff0c;并结合财经领域的数据处理场景&#xff0c;阐述其在财经系统开发中的重要性和应用价值。 MyBatis中的<foreach>标签简介 MyBatis 是一个优秀的持久层框架&#xff0c;它简化了数据库操作的流程&…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装

以下是基于 vant-ui&#xff08;适配 Vue2 版本 &#xff09;实现截图中照片上传预览、删除功能&#xff0c;并封装成可复用组件的完整代码&#xff0c;包含样式和逻辑实现&#xff0c;可直接在 Vue2 项目中使用&#xff1a; 1. 封装的图片上传组件 ImageUploader.vue <te…...

汇编常见指令

汇编常见指令 一、数据传送指令 指令功能示例说明MOV数据传送MOV EAX, 10将立即数 10 送入 EAXMOV [EBX], EAX将 EAX 值存入 EBX 指向的内存LEA加载有效地址LEA EAX, [EBX4]将 EBX4 的地址存入 EAX&#xff08;不访问内存&#xff09;XCHG交换数据XCHG EAX, EBX交换 EAX 和 EB…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

优选算法第十二讲:队列 + 宽搜 优先级队列

优选算法第十二讲&#xff1a;队列 宽搜 && 优先级队列 1.N叉树的层序遍历2.二叉树的锯齿型层序遍历3.二叉树最大宽度4.在每个树行中找最大值5.优先级队列 -- 最后一块石头的重量6.数据流中的第K大元素7.前K个高频单词8.数据流的中位数 1.N叉树的层序遍历 2.二叉树的锯…...

Linux --进程控制

本文从以下五个方面来初步认识进程控制&#xff1a; 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程&#xff0c;创建出来的进程就是子进程&#xff0c;原来的进程为父进程。…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

【Go语言基础【12】】指针:声明、取地址、解引用

文章目录 零、概述&#xff1a;指针 vs. 引用&#xff08;类比其他语言&#xff09;一、指针基础概念二、指针声明与初始化三、指针操作符1. &&#xff1a;取地址&#xff08;拿到内存地址&#xff09;2. *&#xff1a;解引用&#xff08;拿到值&#xff09; 四、空指针&am…...