C#学习

这篇博客探讨了C#中多态的实现原理,解释了编译器如何通过虚函数表和虚表指针确保基类引用调用派生类方法。内容包括:多态的编译器机制,基类与派生类引用类型的转换,以及隐藏基类方法的概念。文章还通过代码示例展示了如何通过强制类型转换调用派生类的特定方法。
摘要由CSDN通过智能技术生成

C#多态实现以及基类与派生类引用类型相互转换的原理

多态实现原理

编译器在编译的时候为每一个含有虚函数的类分配一个虚函数表,生成对象的时候为每一个对象分配一个虚表指针,指向本类的虚函数表。在程序运行期间,当用派生类的对象给基类引用赋值时,就会用派生类的虚表指针覆盖基类的虚表指针,因此在用基类指针调用该方法的时候总能正确的指向派生类所重写的方法.

伪代码:
class A
{ virtual func()}
class B:A
{ func() }

主函数:
A a = new B()
a.func()
-----此时调用的时B中的func 方法,由此实现多态。

A a = new B(),此步骤主要做了三件事:
1.A a – 生成了一个A为模板的引用类型(类似与c/c++中指针变量,实际并没有分配对象内存)。
2. new B()----生成了一个B的对象(分配了内存空间)
3. 将a 引用指向B生成的对象。

我们 知道,当类B继承了类A的时候,B就拥有了A的所有方法及属性。
而此时的引用类型a 则被限定只能调用A范围内的属性方法,调用B方法时会报错。(类A的框没有装B的属性方法)
如果A中的方法为 普通方法,在用a调用的时候就会调用 A中的方法,此为编译期间就决定。如下代码区的tbase.PrintHelloWorld()实际上调用类A 中的方法。
若如果A中的方法为虚方法,调用时则根据多态原理在运行期间覆盖虚指针而实际调用B中方法。如下代码区的tbase.PrintName();

如何用 a 调用B 中方法呢
用强制类型转换把A类型的引用类型强转成B类型(把A的框放大成B了)
TestData tdata = (TestData)tbase;
此时的tdata 就可以访问所有的B属性包括A属性 以及B特有属性。
但是其中有个问题,如果A中方法与B中方法重名----- 如代码中PrintHelloWorld(),此时调用的为何是B中的方法?如输出的第6行
这涉及到派生类对基类方法的 隐藏。
隐藏方法:可以用与基类成员名称相同的成员来屏蔽基类成员。
隐藏数据成员:在派生类中声名名称和类型相同的成员,不需要new关键字。
隐藏函数成员:在派生类中声名新的带有相同函数签名的成员(函数名和函数参数相同即可,对返回值类型无要求),在声名前面加上new关键字。

在此不赘述

—以上为学习过程中记录和感悟。如有错误,欢迎指出。评论区对线哈哈哈

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值