Tin*_*Yun 5 c# oop polymorphism inheritance
当我看到时,我总是感到困惑:
Parent ref = new Child();
Run Code Online (Sandbox Code Playgroud)
其中Child类扩展Parent.
ref在内存中的外观如何?Child ref = new Child();
Run Code Online (Sandbox Code Playgroud)
对象在内存中的外观如何?
你的问题不清楚.有两个相关的内存位置.该变量与存储位置相关联.该存储位置包含对另一个存储位置的引用.
变量的存储位置通常实现为四字节或八字节整数,其中包含"托管指针" - 垃圾收集器已知的内存地址.
对象的内存布局也是CLR的实现细节.与对象关联的内存缓冲区将包含对象的所有数据 - 字段的所有值和诸如此类的东西.它还包含对另一个内存位置的引用,该对象的虚函数表.
然后,虚函数表(vtable)包含更多引用,这次引用引用与最派生类型的对象关联的方法.
如何处理虚拟方法?非虚?
通过从变量中查找对象引用,然后查找vtable,然后在vtable中查找方法,然后调用该方法来执行虚方法.
非虚方法不是通过vtable调用的,因为它们在编译时是已知的.
它与......有什么不同?
在对象上调用的非虚方法将根据变量的类型调用方法的版本.调用对象的虚方法将根据变量引用的对象的类型调用方法的版本.
如果不是很清楚,您可能需要阅读我的文章,该文章解释了如何使用没有它们的语言"模拟"虚拟方法.如果你能理解如何自己实现虚拟方法在没有他们的语言,这将有助于你了解我们是如何真正做实现虚拟方法.
ref是一个Child对象。虚拟方法在类上调用Child。但是,仅在类中定义的方法在分配给对象Child时不可见。Parent
如果foo()不是 virtual,则编译将根据变量的声明类型选择一个方法ref。如果有的Parent ref = new Child();话Parent.foo()就会被叫到。如果有的Child ref = new Child();话Child.foo()就会被叫到。当然,在这种情况下,C# 编译器会要求您new在声明中使用 useChild.foo()来指示您要隐藏 中的实现Parent。