先看代码吧:using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace TestVitual
{
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass bc = new BaseClass();
            Console.WriteLine("@@@");
            DerivedClass dc = new DerivedClass();
        }
    }    class BaseClass
    {
        public BaseClass()
        {
            Console.WriteLine("Base Constructor");
            Fun1();
        }
        public virtual void Fun1()
        {
            Console.WriteLine("Base Fun1");
        }
        public void Fun2(BaseClass dc)
        {
            dc.Fun1();
            Fun1();
        }
    }    class DerivedClass: BaseClass
    {
        public DerivedClass()
        {
            Console.WriteLine("Derived Constructor");
        }
        public override void Fun1()
        {
            Console.WriteLine("Derived Fun1");
        }
    }
}
执行结果如下:
Base Constructor
Base Fun1
@@@
Base Constructor
Derived Fun1
Derived Constructor
请按任意键继续. . .@@@之前的执行结果没什么问题,构造一个基类对象,基类构造函数中调用了Fun1()方法,输出“Base Fun1”。
但是构造派生类对象时,神奇的事情就发生了,首先基类的构造函数会被调用,然后是语句“Fun1()”,从输出上看是调用了派生类的Fun1(),而且派生类确实也重写了基类的虚方法fun1(),但是执行基类构造函数时,派生类的对象还没有被构造出来,那么派生类的Fun1()是谁调用的呢??? 请高手不吝赐教,小弟谢了先~~

解决方案 »

  1.   


    我不知道你有没有学过c++,这种说法是中c++的毒(或者中那些满脑子c++的人的毒)太深的原因。以前有本国外的畅销书是讲解一种流行的c++编译器是如何使用虚拟列表来实现类型继承的,许多人以为那就是面向对象继承的“标准化”解释。站在计算机编程的角度来理解面向对象设计经常会得到非常幼稚的错误。对于面向对象的继承来说(脱离开任何编程语言,面向对象技术成熟了超过20年时间,早先的著作最准确),DerivedClass继承自BaseClass ,就是说一个DerivedClass对象a同时也就是(is_a)一个BaseClass对象a,根本就是同一个对象。.net的实现是更加接近面向对象理论的。而那些受某些c++书籍影响的人却说:一个DerivedClass类型的对象内部的有一个private(内部)对象再引用一个父类BaseClass类型的对象,这是错误概念。当对dc操作的时候,不论方法是在哪一个class里边定义的,都是在DerivedClass类型的对象上执行,而不是什么“基类的对象、派生类的对象”。当你定义“class DerivedClass: BaseClass”的时候,编译器就会自动在BaseClass的实例化方法中插入引用DerivedClass的实例化代码,而这个代码的最后是“this.Fun1();”,而这个this不是什么“基类的对象”,根本没有这种东西。你不妨把基类的实例化方法增加一行代码:        public BaseClass()
            {
                Console.WriteLine("Base Constructor");
                Fun1();
                Console.WriteLine("我的类型是{0}", this.GetType().Name);
            }
    看看输出。记住,那种c++思想是偏颇的,违背了面向对象分析设计的原则。
      

  2.   

    sp1234的解释够清楚了...lz中毒很深...
      

  3.   

    不论你在BaseClass还是DerivedClass中打印this.GetType().Name以及this.GetHashCode(),都会打印出这两个实例化方法都是运行在DerivedClass类型实例化对象上,而且是同一个对象(HashCode相同)。这说明.net在这个方面是符合面向对象的概念的。
      

  4.   

    稍作修改,看的清楚一点
    using System;public class B
    {
        public B()
        {
            Console.WriteLine("ClassB!");
            this.Func();
        }    public virtual void Func()
        {
            Console.WriteLine("ClassB-Func!");
        }
    }public class BB:B
    {
        public BB():base()//变为显式
        {
            Console.WriteLine("ClassBB!");
            this.Func();
        }    public override void Func()
        {
            Console.WriteLine("ClassBB-Func!");
        }
    }class Test
    {
        static void Main()
        {
            BB aa = new BB();
            Console.ReadKey();
        }
    }
    楼上的讲的一点也不错,没问题。
    算是推断,希望能表述地更理论一点。
    C#中好象有一个叫“判定”的机制~~
      

  5.   


    using System;public class B
    {
        public B()
        {
            Console.WriteLine("ClassB!");
            this.Func();
        }    public virtual void Func()
        {
            Console.WriteLine("ClassB-Func!");
        }
    }public class BB:B
    {
        public BB():base()
        {
            Console.WriteLine("ClassBB!");
            this.Func();
        }    public override void Func()
        {
            base.Func();//原方法在这里,还是可以调用自身的
            Console.WriteLine("ClassBB-Func!");
        }
    }class Test
    {
        static void Main()
        {
            BB aa = new BB();
            Console.ReadKey();
        }
    }
    多谢楼主,提供了一个,没有类型转换,但是产生“多态”的非典型案例~~补充进来:
    http://topic.csdn.net/u/20090805/13/254df2c5-2356-438a-a7f5-7f9ce5a9b3b0.html?13283
      

  6.   

    多谢sp1234以及在夜深人静时回帖的朋友们,能不能再请教一下,当构造派生类对象时,类中函数成员的代码是在何时加载到内存中的,它在基类构造函数中可以被调用,那么在基类构造函数执行之前就已经加载了? 可否给小弟讲解一下实例化一个类的过程? 
    PS:
    小弟以前是C++的,最近刚刚转C#,有好多疑惑的地方还要靠大家多多指教,Thank you everyone!!!
      

  7.   


    终于找到反证了,首先明确一下观点:
    [1]sp1234认为:这个this不是什么“基类的对象”。
    [2]pcnetman888认为:这个this正是“基类的对象”。新问题在此:
    http://topic.csdn.net/u/20090811/22/fb80c433-8dff-4ebe-8b3a-ea47767c7e7d.html
      

  8.   


    to:vrhero
    我认为你还是很有研究精神,至少理论基础还挺扎实的,
    但在论论一些比较"基础"问题时,请不要那么轻易下结论好吧.我先检讨一下自己犯下的错误,
    不该简单的用"this"来说事,我本意是想说明此"this"非彼"this",
    但实在找不到更好的替代"名词",this.type()确能说明问题,但我要的不是这个表面的效果.你有兴趣的话,我们可以辩一下,我把问题先缩小一下范围:
    在6楼的代码中,在基类和扩展类中,    //扩展类的
        public BB():base()
        {
            Console.WriteLine("ClassBB!");
            this.Func();
        }    //基类的
        public B()
        {
            Console.WriteLine("ClassB!");
            this.Func();
        }
    上面两个代码片断中的,且先不论this的作用.
    this.Func();
    [1]两个this.Func(),其作用是否相同?
      

  9.   

    忘了被充一下了:
    很多在"语法"上的理论(这些在MSDN上未必能找到,但在老外的论坛里很多~~),
    往往在作用在"构造"函数上,
    会变的很特殊,不同与一般的函数调用,
    后面,我会来证明这个观点....