13里氏转换
里氏转换
1)、子类可以赋值给父类
2)、如果父类中装的是子类对象,那么可以讲这个父类强转为子类对象。
里氏转换就是将父类转换为合适的子类,或者是用子类代替一下父类,也就是将子类对象给父类
作用
子类对象可以调用父类中的成员,但是父类对象永远都只能调用自己的成员。一开始只有儿子能用爹的方法,里氏转换后,爹也能用儿子的方法了,差不多就是继承的话,子类继承父类,子类能调父类,但是父类不能。但是你把一个子类对象给父类的话,父类就可以转为子类,然后就能使用子类的方法,如果父类没有包含子类,也就是没有把子类给父类,父类就不能强转为子类,就是一个子类对象可以在继承关系里来回转,只不过成派生类时转回基类需要显式。
孙子类也可以通过里氏转将值赋值给爷爷辈,同样爷爷辈如果装的是孙子辈的实例,也可以强制转为孙子辈。所以,实例化孙子辈的时候会调用父类的构造方法,然后调用爷爷辈的构造方法,最后调用自己的。
比如:现在有三个类
基类:Person
派生类:Teacher、Student
将子类对象给父类,
Student student = new Student();
Person person = student;
//或者直接这样写
Person person = new Student();
里氏转换,因为子类继承了父类,并且子类新建对象时在内存中已经开辟了父类的内存空间(可以在子类和父类中分别写无参构造函数测试,在new子类对象实例的,会先调用父类的无参构造方法,然后再调用自己的构造方法),
因此可以将新建一个父类类型,然后将子类的实例赋值给父类.
将装有子类对象的父类转为子类
Person person = new Student();
Student s = (Student)person;//将子类对象赋值给父类,再将父类中的子类对象强制转换成子类
将装有子类对象的父类转为其他子类
Person person = new Student();
Teacher t = (Teacher)person;//这样会 报异常,因为当前父类 装的 是 student这个子类,而不是Teacher这个子类
这样会报异常,因为当前父类里面并没有装Teacher类,而是装的Student类
判断是否能转
is:表示类型转换,如果能够转换成功,则返回一个true,否则返回一个false
as:表示类型转换,如果能够转换则返回对应的对象,否则返回一个null
将子类转父类用is判断结果是为true的,as的话结果也不是为null
子类里面都包含了父类,所有子类都可以转为父类
is
Person person = new Student();
if (person is Teacher)
{
Teacher t = (Teacher)person;
t.Teach();
}
else
{
Console.WriteLine("转换失败 ");
}
as
Person person = new Student();
Teacher t = person as Teacher;//转换失败,结果为空
练习,有六个类
基类:Person
派生类:Student、Teacher、MeiNv、ShuaiGe、YeShou
目的,每个类都有自己的SayHi方法,要求每次运行在控制台随机输出十个不同类的SayHi方法
Person[] personArray = new Person[10];
Random r = new Random();
int random = 0;
for (int i = 0; i < personArray.Length; i++)
{
random = r.Next(1, 7);
switch (random)
{
case 1:
personArray[i] = new Student();
break;
case 2:
personArray[i] = new Teacher();
break;
case 3:
personArray[i] = new MeiNv();
break;
case 4:
personArray[i] = new ShuaiGe();
break;
case 5:
personArray[i] = new YeShou();
break;
case 6:
personArray[i] = new Person();
break;
}
}
for (int i = 0; i < personArray.Length; i++)
{
if (personArray[i] is Student)
{
Student s = (Student)personArray[i];
s.StudentSayHai();
}
else if (personArray[i] is Teacher)
{
Teacher t = (Teacher)personArray[i];
t.TeacherSayHai();
}
else if (personArray[i] is MeiNv)
{
MeiNv m = (MeiNv)personArray[i];
m.MeiNvSayHai();
}
else if (personArray[i] is YeShou)
{
YeShou y = (YeShou)personArray[i];
y.YeShouSayHai();
}
else if (personArray[i] is ShuaiGe)
{
ShuaiGe sg = (ShuaiGe)personArray[i];
sg.ShuaiGeSayHai();
}
else
{
personArray[i].PersonSayHai();
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构