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

article/2025/10/3 8:53:44

向上转型和向下转型的利弊

一、向上转型
好处:隐藏了子类型,提高了代码的扩展性。
坏处:只能使用父类的功能,不能使用子类特有功能,功能被限定。
使用场景:不需要面对子类型,通过提高扩展性,或者使用父类的功能即可完成操作,就是使用向上转型。
二、向下转型
好处:可以使用子类型的特有功能
坏处:面对具体的子类型,向下转型具有风险。即容易发生ClassCastException,只要转换类型和对象不匹配就会发生。解决方法:使用关键字instanceof。

C#篇

向上转型&&向下转型

  • 向上转型:子类对象赋给父类,转型成功
  • 向下转型:父类对象赋给子类,要注意类型匹不匹配的问题,容易出错,转化失败对象值为null
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;namespace _TBD_2020814Test
{class Animal { }class Cat : Animal{}class Dog : Animal { }class Hashiqi : Dog { }class Program{static void Main(string[] args){//向上转型(子类->父类)转型成功//狗是动物,Animal a = new Dog();Dog d0 = a as Dog;Console.WriteLine(d0);//dog//进来一只狗,不认识说他是一只动物,属于向上转型//然后再对它说它是一只狗//因为本来就是一只狗,所以没问题//向下转型(父类->子类)转型失败输出null// Dog d1 = (Dog)new Animal();// Console.WriteLine(d1);异常Dog d2 = new Animal() as Dog;//动物被叫做狗Console.WriteLine(d2);//null//向下转型要注意类型匹不匹配的问题//一只猫也是一只动物,硬性被说是狗,就会发生错误}}
}

示范代码:

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;namespace _TBD_2020814Test
{class Animal { }class Cat : Animal { }class Dog : Animal { }class Hashiqi : Dog { }class Program{static void Main(string[] args){//向下转型(父类->子类)转型失败输出null//错误示范Animal a = new Animal();Dog d2 =a as Dog;Console.WriteLine(d2 is Dog);//falseConsole.WriteLine(d2==null);//true//正确示范Animal a1 = new Dog();Dog d = a1 as Dog;Console.WriteLine(d is Dog);//TrueConsole.WriteLine(d == null);//False}}
}

注意:
向上转型后,子类不能使用原来子类中特有的字段,

向下转型后,父类可以使用子类中特有的字段,注意有没有异常,可以用is判断

关键字as+is

  • as强制类型转换
  • is判断数据类型

代码示例:

using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;namespace _TBD_2020814Test
{class Animal {public string name;public int age;}class Dog : Animal {public char gender;}class Hashiqi : Dog {public string kind;}class Monkey : Animal{ }class Lion : Animal { }class Tiger : Animal { }class Program{static void Main(string[] args){//实例化一个Dog对象Dog d = new Dog();d.name = "";d.age = 3;d.gender = 'f';//向上转型(狗赋值给动物)Animal a = d;a.name = "";a.age = 1;//a.gender = 'f';狗的gender字段不能使用Dog dd = a as Dog;//a本来就是狗,所以狗的gender可以使用dd.gender = 'f';//向下转型(把狗赋值给哈士奇)/*Hashiqi h = a as Hashiqi;//nullh.kind = "";//异常*/RecordAnimal(new Hashiqi());}public static void RecordAnimal(Animal a) { //如果是哈士奇,打印if(a is Hashiqi)//is关键字{Console.WriteLine("本园不收哈士奇!!!");}}}
}

基础知识

Java中的继承机制使得一个类可以继承另一个类,继承的类称为子类,被继承的类称为父类。在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合起来形成一个子类的对象,所以子类可以继承父类中所有的属性和方法,包括private修饰的属性和方法,但是子类只是拥有父类private修饰的属性和方法,却不能直接使用它,也就是无法直接访问到它(子类可以通过调用父类的public声明的get方法来获取父类的private属性,但无法访问父类的private方法)。同时子类可以对继承的方法进行重写(@Override),并且新建自己独有的方法。

Java篇

1.向上转型:

假设有一个Fruit类,Fruit类中有一个show()方法,代码如下:

class Fruit{public void show() {System.out.println("this is a fruit");}
}

有一个Apple类继承自Fruit类,该类有自己的方法test(),并且重写了父类的show()方法,代码如下:

class Apple extends Fruit{@Overridepublic void show() {System.out.println("this is a apple");}public void test() {System.out.println("i am a apple");}
}

实例化Apple类,并新建一个Fruit类的引用变量引用该实例,调用实例的show()方法:

Fruit fruit = new Apple();
fruit.show();

结果为:
在这里插入图片描述
调用实例的test()方法:

fruit.test();

结果报错:
在这里插入图片描述
分析:

这里用到了向上转型,换言之,就是用父类的引用变量去引用子类的实例,这是允许的。当向上转型之后,父类引用变量可以访问子类中属于父类的属性和方法,但是不能访问子类独有的属性和方法。例子中由于子类重写了父类的show()方法,所以调用的show()方法是子类的show()方法,输出结果为:“this is a apple”,而调用子类的test()方法则会报错。
2.向下转型

并不是所有的对象都可以向下转型,只有当这个对象原本就是子类对象通过向上转型得到的时候才能够成功转型。

实例化Apple类,并新建一个Fruit类的引用变量“fruit”引用该实例,然后新建一个Apple类的引用变量,引用向下转型的“fruit”变量,代码如下:

Fruit fruit = new Apple();
Apple apple = (Apple) fruit;

上述代码是允许的,因为fruit引用的对象原本就是Apple对象向上转型得到的,在对fruit向下转型后得到的还是Apple类的对象,能够被Apple类的引用变量引用。

假设有一个Orange类继承自Fruit类,代码如下:

class Orange extends Fruit{@Overridepublic void show() {System.out.println("this is a Orange");}public void test() {System.out.println("i am a Orange");}
}

实例化Apple类,并新建一个Fruit类的引用变量“fruit”引用该实例,然后新建一个Orange类的引用变量,引用向下转型的“fruit”变量,代码如下:

Fruit fruit = new Apple();
Orange orange = (Orange) fruit;

上述代码虽然能够编译成功,但是在运行的时候会报错,因为fruit对象是由Apple对象向上转型得到的,只能够向下转型成Apple对象,不能够向下转型成Orange对象。

3.转型的好处

通过向上向下转型肯定是有好处的,比如可以减少编程代码。

假设在主类中定义了一个run()方法,该方法传入一个Fruit参数,并调用了Fruit对象的show()方法,代码如下:

public static void run(Fruit fruit) {fruit.show();}

在main()方法中的代码如下:

public static void main(String[] args) {run(new Fruit());run(new Apple());run(new Orange());}

上述代码中,调用run()方法时的参数不仅是Fruit对象,也可以是Apple对象和Orange对象,当传入的是Apple对象和Orange对象时,就会向上转型成Fruit对象,但是调用的show()方法还是Apple对象和Orange对象的show()方法。这样就不需要在主类中同时重载三个run()方法,减少了代码量。

源自

C#学习-多态(向上转型&&向下转型&&as关键字&&is关键字)

Java对象类型向上转型和向下转型


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

相关文章

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…

指示函数 indicator function

指示函数 基本定义 指示函数(indicator function)   数学中,指示函数是定义在某集合X上的函数,表示其中有哪些元素属于某一子集A。   指示函数有时候也称为特征函数。现在已经少用这一称呼。概率论有另一意思迥异的特征函数。…