class A
{
public virtual void M()
{
MessageBox.Show("AM");
}
}
class B : A
{
public override void M()
{
MessageBox.Show("BM");
}
}
class C : B
{
public new virtual void M()
{
MessageBox.Show("CM");
}
}
class D : C
{
public override void M()
{
MessageBox.Show("DM");
}
}如上4個類
如下定義D d = new D();
A a = d;
B b = d;
C c = d;
如下執行:
a.M();
b.M();
c.M();
d.M();求上面四個執行語句的結果及詳細原因(最重要是原因)
{
public virtual void M()
{
MessageBox.Show("AM");
}
}
class B : A
{
public override void M()
{
MessageBox.Show("BM");
}
}
class C : B
{
public new virtual void M()
{
MessageBox.Show("CM");
}
}
class D : C
{
public override void M()
{
MessageBox.Show("DM");
}
}如上4個類
如下定義D d = new D();
A a = d;
B b = d;
C c = d;
如下執行:
a.M();
b.M();
c.M();
d.M();求上面四個執行語句的結果及詳細原因(最重要是原因)
BM
DM
DMoverride会覆盖实现,无论你用什么基类型引用它。
new就是另起炉灶,用该类型与在其基础上衍生的类型引用时,会调用该方法或者其覆盖方法。但是当用该类型的积累性引用时,该new方法就象不存在一样。
{
class A
{
public virtual void M() //生成一个方法虚函数表
{
Console.WriteLine("AM");
}
}
class B : A
{
public override void M() //更新m虚函数地址,虚函数表指向a
{
Console.WriteLine("BM");
}
public virtual void M(object a) //建立m(o)虚函数表。这里如果注释掉会看到一些结果。
{
Console.WriteLine("CM2");
}
}
class C : B
{
public new virtual void M() //生成新的虚函数表,建立c.m地址
{
Console.WriteLine("CM");
}
//public virtual void M(object a) //生成新的虚函数表,作用和new的近似
//{
// Console.WriteLine("CM2");
//}
}
class D : C
{
public override void M() //覆盖c.m的虚函数地址。虚函数表的地址指向c
{
Console.WriteLine("DM");
}
public override void M(object a)//覆盖c.m的虚函数地址。虚函数表的地址指向b
{
Console.WriteLine("DM2");
}
}
static void Main(string[] args)
{
D d = new D();
A a = d;
B b = d;
C c = d;
a.M(); //查询a的虚函数表.执行b.m函数地址
//a.M(null);
b.M(); //查询a的虚函数表.执行b.m函数地址
b.M(null);
c.M(); //查询c的虚函数表地址.执行d.m函数地址
c.M(null);
d.M(); //查询c的虚函数表地址。执行d.m函数地址
d.M(null);
}
}
BM
BM
DM2
DM
DM2
DM
DM2
请按任意键继续. . .
分析。
D d = new D(); 生成一个类
A a = d;
B b = d;
C c = d;
a.M();
//a.M(null);
b.M();
b.M(null);
c.M();
c.M(null);
d.M();
d.M(null);总结:
因此,虚函数其实有虚函数表地址和虚函数地址2个组成。而所谓类,其实就是记录类数据结构方式罢了。
D d = new D(); 生成一个类
A a = d; 答完結帖
================
生成一个D的实例,并获得对它的一个D类型引用
A a = d;
================
获得d的一个A类型引用,如果是自A覆盖的方法,将使用最后一次(除了被new截断的)覆盖的方法