VB.NET中两类基类引用派生类对象场景的判定咨询
基类引用派生类对象的场景判定
场景1判定结论
你的理解完全正确,两处代码都属于标准的基类引用派生类对象场景,依据如下:
Dim b As Base = DirectCast(d, Base):变量b的静态声明类型是基类Base,实际引用的内存对象是派生类Derived的实例d,完全符合定义。这里的DirectCast只是显式完成了从派生类到基类的转换,本质和隐式转换没有区别。Dim new_b As Base = New Derived():变量new_b的静态声明类型同样是基类Base,实际引用的是刚创建的Derived类实例,属于同一类场景。- 补充:VB.NET中所有引用类型变量本身不存储对象实体,仅存储指向堆内存对象的地址,判定标准从来都是「变量的声明静态类型为基类 + 实际指向的堆对象是派生类实例」,和有没有显式写类型转换代码无关。
场景2判定结论
Me.testMethod()所在的Me,在派生类实例调用基类继承方法的场景下,本质就是基类类型的引用指向派生类对象,和场景1里的b、new_b没有本质区别,完全属于基类引用派生类对象的范畴,核心逻辑如下:
- 首先明确
Me的本质:VB.NET编译器会为每个实例方法自动注入隐藏的Me参数,这个参数的静态编译类型就是方法所属类的类型。比如baseClass类里定义的useMe方法,它内部的Me参数静态类型就是baseClass——和你手动在方法里写Dim meRef As baseClass = 当前对象没有任何差异。 - 当你用派生类实例
testObj调用从基类继承来的useMe方法时,传给Me参数的实际实参,就是这个derivedClass的实例本身。此时Me完全满足「基类静态类型 + 实际指向派生类实例」的判定条件,和场景1的写法没有本质区别。 - 你代码里的运行结果也能印证这个逻辑:正是因为
Me是基类类型引用、指向派生类实例,调用Me.testMethod()时才会触发多态分派,执行派生类重写的方法,输出"Derived Class String"。如果Me实际指向的是纯基类实例,根本不会触发重写逻辑。 - 常见认知偏差澄清:很多人误以为
Me指向当前调用者的类型,所以不算基类引用,但实际上面向对象语言里的继承方法内部,Me的静态类型从定义开始就是基类,运行时指向什么类型的实例,只取决于调用这个方法的对象本身,不会因为方法定义在基类内部就改变引用的类型判定规则。
内容的提问来源于stack exchange,提问作者Sougata
相关产品推荐
相关产品推荐

