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();求上面四個執行語句的結果及詳細原因(最重要是原因)

解决方案 »

  1.   

    BM
    BM
    DM
    DMoverride会覆盖实现,无论你用什么基类型引用它。
    new就是另起炉灶,用该类型与在其基础上衍生的类型引用时,会调用该方法或者其覆盖方法。但是当用该类型的积累性引用时,该new方法就象不存在一样。
      

  2.   

    class Program
        {
            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个组成。而所谓类,其实就是记录类数据结构方式罢了。
      

  3.   

    忘说了。new一般的人说是隐藏。我个人认为,其实是类结构中略去了先前的地址而已。但还存在。override则是改写,原来的地址就不存在了。
      

  4.   

    MSDN:“调用虚方法时,将为重写成员检查该对象的运行时类型。将调用大部分派生类中的该重写成员,如果没有派生类重写该成员,则它可能是原始成员。”我的理解:http://blog.csdn.net/happyhippy/archive/2006/10/02/1317830.aspx补充:new在这里的作用只是为了消除编译器的警告,而无其他任何作用。
      

  5.   

    非常感謝各位,最後一小問題,如下語句代表什麼,有什麼意義
    D d = new D(); 生成一个类
    A a = d; 答完結帖
      

  6.   

    D d = new D();
    ================
    生成一个D的实例,并获得对它的一个D类型引用
    A a = d; 
    ================
    获得d的一个A类型引用,如果是自A覆盖的方法,将使用最后一次(除了被new截断的)覆盖的方法
      

  7.   

    保存網址:http://blog.csdn.net/moxcm/archive/2006/10/30/1357247.aspx
      

  8.   

    保存網址:http://www.microsoft.com/china/msdn/events/webcasts/shared/webcast/consyscourse/Modern.aspx
      

  9.   

    保存http://www.itpub.net/475824.html