类中的向上转型与向下转型详解

article/2025/10/3 8:08:29

我们的类与类之间会存在继承关系,子类继承父类,一个父类可以有多个子类,例如Animal类就可以有Cat子类,Dog子类,等等。那么我们在运用的时候根据不同的场景会出现向上转型和向下转型的情况。

一、向上转型

1、Animal a1 = new Cat();
2、Cat cat = new Cat();
 Animal a2 = cat;
这两种情况都是向上转型:一个父类引用指向一个子类实例

向上转型的意思:
假设我们现在有一只小猫,我可以说我喂了动物,也可以说我喂了小猫,这两种说法都是没有问题的,因为嘟嘟就是动物。

向上转型会发生的三种情况:
1、直接赋值

Animal a1 = new Cat();

a1是一个父类Animal的引用指向一个子类Cat的实例。
当我们在用a1这个对象的时候,a1只能调用出父类Animal里有的引用,若调用的方法在子类Cat里有同名方法那么实际调用的是子类里的该方法。
通过代码看一下:

//我们定义了一个Animal类
public class Animal {public String name;public Animal(String name){this.name=name;}//父类中的eat方法public void eat(String food){System.out.println("父类Animal的eat方法");}
}
//定义一个Cat类并继承Animal类
public class Cat extends Animal {public Cat(String name) {super(name);}//子类中的eat方法@Overridepublic void eat(String food) {System.out.println("子类Cat类的eat方法");}
}//我们最终进行一个测试
public class test {public static void main(String[] args) {//a1是一个Animal父类的引用指向子类Cat的实例Animal a1=new Cat("嘟嘟");//调用eat方法a1.eat("小鱼");}
}

若我们最终输出“父类Animal的eat方法”那么就调用的是父类的该方法,若实际输出“子类Cat类的eat方法”那么就调用的是子类的该方法。
在这里插入图片描述
我们发现最终实际调用的是子类的该方法。所以能调用什么方法看引用的类型存在什么方法,实际调用的是实例类里的具体方法。

2、方法传参
当我们创建了一个方法,规定传入的参数是一个父类,在实际调用的时候我们可以直接传入这个父类的子类作为参数,程序也会正确运行。

//还是刚才的两个类,创建一个ani方法
public class test {public static void ani(Animal animal){System.out.println(animal.name+" is an animal !");}public static void main(String[] args) {Cat cat = new Cat("嘟嘟");//方法定义的时候规定的参数类型是Animal//我们这里直接传入一个Cat类对象ani(cat);}
}

在这里插入图片描述
方法调用成功!

3、方法返回值
当我们创造了一个方法,设定方法的返回值为父类,我们在实际返回的时候返回该父类的子类时也是没有问题的。

//还是刚才的方法,将方法的返回值规定为Animal
public class test {public static Animal ani(Animal animal){System.out.println(animal.name+" is an animal !");return animal;}public static void main(String[] args) {Cat cat = new Cat("嘟嘟");//调用ani方法并打印返回值System.out.println(ani(cat));}
}

在这里插入图片描述
我们发现方法可以正确执行,并且返回了一个Cat类的对象。

二、向下转型

子类 子类引用 = (子类)父类引用
这就是向下转型的方式

当我们根据父类创建了一个子类,子类继承了父类的特性,之后延又展出了新的独有的属性和方法。我们先将子类进行了向上转型后利用,向上转型后编译器只能调用父类有的方法和属性,若我们想调用该子类独有的属性和方法时,就需要将向上转型后的父类向下转型才可以使用。

Animal a1 = new Bird(); //向上转型
Bird bird = (Bird)a1; //将a1向下转型为Bird类

我们在向下转型的时候会出现异常,例如:

Animal a2 = new Cat();
Bird bird = (Bird)a2;

这种情况就会出现异常!
因为我们首先将一个Cat类对象向上转型为Animal类,但是我们在向下转型的时候不能强制将其转为Bird类。上一段代码没有问题是因为该对象本事是一个Bird类向上转型后就像披上了一个Animal的外衣,再一次脱掉外衣还是原本的Bird,但是这次给Cat类披上Animal外衣后让他脱掉外衣变成Bird就会出现错误。

当我们面对这个错误的时候就可以利用关键字instanceof来帮助我们。

A instanceof B

instanceof关键字帮我们判断一个引用A向下转型后是否为B类,若是则返回true,若不是则返回false。

Animal a2 = new Cat();
//判断a2向下转型后是否为bird类
if ( a2 instanceof bird )
{
  //若是才执行括号内的程序
  Bird bird = (Bird)a2;
}

利用instanceof关键字就可以帮助我们判断向下转型是否正确,就可以规避一些转型错误的问题!


http://chatgpt.dhexx.cn/article/IrFHMG3O.shtml

相关文章

【基础知识】向上转型和向下转型

向上转型和向下转型的利弊 一、向上转型 好处:隐藏了子类型,提高了代码的扩展性。 坏处:只能使用父类的功能,不能使用子类特有功能,功能被限定。 使用场景:不需要面对子类型,通过提高扩展性&am…

Java向上转型的作用(有详细代码介绍)

今天看到一道Java的练习题,题目如下 当时对于主函数中 Car car (Car) new Benz(); 不是很理解,也并不知道有什么意义,因为如果仅仅写Car car new Benz(); 程序运行结果是一样的。 在经过阅读书籍和查看别的博主写的关于向上向下转型的…

MATLAB三维数组转为二维数组(时间序列分析中很有用)

在MATLAB中三维数组转二维的方法 一、写该程序的初衷 在处理时间序列遥感数据的时候,我之前的做法是: 将时间序列数据读取为三维矩阵;将该数据保存为BIP格式;在每个像元上进行循环,取出其第三维(比如有46…

Matlab一维数组及其应用

目录 1.一维数组 2.与一维数组相关的函数 3.一维数组在二维绘图中的应用 4.在已存在的图形上添加新图形 5.在一个图形窗口中绘制多个子图 6.一维数组在一元多项式运算中的应用 1.一维数组 数值数组(简称为数组)是Matlab中最重要的一种内建数据类型。数组运算是Matlab软件…

matlab 二维数组声明,Matlab字符串函数及二维数组

Matlab字符串函数及二维数组 发布时间:2017年07月28日 评论数:抢沙发 阅读数:833 strcmp(Str1,Str2),finder(S,s),strcat(S1,S2),disp(str)>> str1 str1 I am a man >> str2 str2 Iamaboy >> strcmp(str1,str2) %比较str1和str2 相同…

MATLAB 二维数组的行列操作

首先定义一个3*3的二维数组 data [1,2,3;4,5,6;7,8,9];第一列 data(:,1)第一行 data(1,:)第一列前两个数 data(1:2,1)按列展开 data(:)从第五个数到最后 data(5:end)对ADC的数据IQ分开,对应一列数据,行数据根据逗号交换 IDATAadc_data_mux(1:2:en…

复习matlab 基础知识

1、 2、a.*b就是说两个矩阵的对应元素一次相乘。 [a,b,c,d] 将数组显示。 3、for k 1:lebgth(S) 语句体 end 4、 4、while循环 while Boolean 语句体 end 5、 6、 7、break and continue break:跳出循环体,结束整个循环。 continue&#xff1a…

【Matlab编程】新手入门第三天

第三章 数组 前言1.数组的创建1.1创建多维数组 2.数组的属性2.1数组结构2.2数组大小2.3数组的维度2.4数组数据类型 3.数组操作3.1数组索引和寻址3.2数组的查找3.3数组的排序 4.关系运算和逻辑运算总结 前言 MATLAB中的数组无处不在,任何变量在MATLAB中都是以数组的…

matlab二维数组的创建及其变换

很基础的问题,但很容易忘记。。 1、MATLAB中,一般使用方括号([]),逗号(,),分号(;)与空格来创建二维数组。空数组是一种非常特殊的数组…

strptime() 函数

查看更多 https://www.yuque.com/docs/share/54ad7ca7-b9cb-4d8b-a25f-c6e3ca349648

Python中的时间函数strftime与strptime对比

这两个函数,初看真是一脸懵逼,不是同一个么,对于小萌新来说,多少有点晕菜了,随时可能把两者混淆,导致程序报错或者出现小bug,查询了几个小时,到最后才发现竟然一个字母的差别.......…

python中datetime模块中strftime/strptime函数

python中datetime模块非常好用,提供了日期格式和字符串格式相互转化的函数strftime/strptime 1、由日期格式转化为字符串格式的函数为: datetime.datetime.strftime() 2、由字符串格式转化为日期格式的函数为: datetime.datetime.strptime() 3、两个函数都涉及日期…

strftime()函数

C 库函数 : size_t strftime(char *str, size_t maxsize, const char *format, const struct tm *timeptr) 根据 format 中定义的格式化规则,格式化结构 timeptr 表示的时间,并把它存储在 str 中。 参数说明: str -- 存储产生的结果。maxsize -- 结果可存储的最大size。fo…

strftime和strptime使用(时间日期的格式控制函数)

strftime和strptime使用 整理自《linux程序设计》 这两个函数都是时间日期的格式控制函数,在功能上看起来正好相反。strftime将一个tm结构格式化为一个字符串,strptime则是将一个字符串格式化为一个tm结构。 strftime 函数原型:size_t strfti…

符号函数与指示函数

1.符号函数——sign(x) 2.指示函数——

函数的声明和定义

一、函数声明: 1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数声明决定不了。 2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。 3. 函数的声明一般要放在头文件中的。 二、…

main函数的一些操作

系列文章目录 第一章 OC之单例模式 第二章 OC之对象初始化 第三章 OC之类和协议 第四章 OC之main函数中的操作和一些概念 文章目录 系列文章目录前言一、main函数的一些操作二 属性和成员变量三 和isEqual四 分类和拓展五 NSString的三种类型1._NSCFConstantString2._NSCFStri…

函数的介绍

自话函数 函数这一概念,之前在数学中是最常见的。但不要忘记最初设计计算的前辈都是一些数学大家。所以函数这一概念自然也被引入到了计算机中。 数学中函数表示的一种映射关系(集合A到集合B之间的关系),而到了计算机中这一概念被延伸。 计算机中函数由…

S函数介绍

S函数介绍 S函数中使用文本方式输入公式和方程,适合复杂动态系统的数学描述,并且在仿真过程中可以对仿真参数进行更精确的描述。 S函数模块是整个Simulink动态系统的核心。 S函数时系统函数(system function)的简称,是…

指示函数(indicator function)

1. 计数器 指示函数表示 其中有哪些元素属于某一子集的次数,及满足某一断言或条件的统计; 比如Hamming Loss: 其中 2. 二维的离散指示函数 ⇒ assignment solution xij∈{0,1…