继承关系的类定义 1
class C
{
public virtual void C_M_Public() { Console.WriteLine("C::C_M_Public()"); }
}
class C1 : C
{
public override void C_M_Public() { Console.WriteLine("C1::C_M_Public()"); }
}
class C11 : C1
{
public overrid void C_M_Public() { Console.WriteLine("C11::C_M_Public()"); }
}
测试代码
class Test
{
static void Main(string[] args)
{
//说明:整个过程生成的是C11类型的对象,转换的只是对象的引用类型
C11 c11_c11 = new C11(); //C11—C11对象
C1 c1_c11 = (C1)c11_c11; //C1---C11对象
C c_c11 = (C)c11_c11; // C----C11对象
c_c11.C_M_Public();
c1_c11.C_M_Public();
c11_c11.C_M_Public();
}
}
定义1测试结果如下:override
C11::C_M_Public()
C11::C_M_Public()
C11::C_M_Public()
请按任意键继续. . .
继承关系的类定义 2
class C
{
public virtual void C_M_Public() { Console.WriteLine("C::C_M_Public()"); }
}
class C1 : C
{
public override void C_M_Public() { Console.WriteLine("C1::C_M_Public()"); }
}
class C11 : C1
{
public new void C_M_Public() { Console.WriteLine("C11::C_M_Public()"); }
}
测试代码
class Test
{
static void Main(string[] args)
{
//说明:整个过程生成的是C11类型的对象,转换的只是对象的引用类型
C11 c11_c11 = new C11(); //C11—C11对象
C1 c1_c11 = (C1)c11_c11; //C1---C11对象
C c_c11 = (C)c11_c11; // C----C11对象
c_c11.C_M_Public();
c1_c11.C_M_Public();
c11_c11.C_M_Public();
}
}
定义2的测试结果如下:new 这个测试结果本人刚开始有点纳闷(还是因为理解不深,也不知道这东西到底有多深)
运行结果如下:
C1::C_M_Public() ?????引用时C类型,实例对象是C11类型,调用的却是C1类型的方法???????
C1::C_M_Public()
C11::C_M_Public()
请按任意键继续. . .
个人分析:
我们看看Mian的IL代码如下:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// 代码大小 33 (0x21)
.maxstack 1
.locals init ([0] class InheritTest.C11 c11_c11,
[1] class InheritTest.C1 c1_c11,
[2] class InheritTest.C c_c11)
IL_0000: nop
IL_0001: newobj instance void InheritTest.C11::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: stloc.1
IL_0009: ldloc.0
IL_000a: stloc.2
IL_000b: ldloc.2
IL_000c: callvirt instance void InheritTest.C::C_M_Public()// C 虚方法,运行时多态性
IL_0011: nop
IL_0012: ldloc.1
IL_0013: callvirt instance void InheritTest.C::C_M_Public()//C1 override虚方法,运行时多态性
IL_0018: nop
IL_0019: ldloc.0
IL_001a: callvirt instance void InheritTest.C11::C_M_Public()// C11 new 编译时确定要调用的方法,编译时多态性
IL_001f: nop
IL_0020: ret
} // end of method Test::Main
针对用C类型引用调用该方法时,它却调用了C1类型的该方法 实例对象可是C11类型的阿 个人分析原因如下:
C#编译器编译后,这个方法调用被标记为虚方法调用,具体要调用什么方法要等到运行时指向的实例对象是什么类型,测试中 在运行时我们生成的是C11类型的实例对象,C11类型本身可并没有override这个方法,只有new 这个方法,但它的基类C1却有override这个方法,所以调用了它的基类C1的该方法;
这样的分析如果有不足,请大家多多指教!!至于CLR是如何来实现虚方法的调用,本人的理解还没有到那个层次。