构造函数的调用顺序是先调用System.Object,再按照层次结构由上向下(基类=》派生类)进行,直到到达编译器要实例化的类为止。在此过程中,每个构造函数都初始化自己类中的字段。编译器先自下而上查找构造函数,然后再自上而下地执行。

       以下通过示例说明派生类的构造函数是如何执行的。

1.基类和派生类都未显示定义构造函数

      执行GenericCustomer customer = new Nevermore60Customer();语句时,编译器首先找到试图实例化的类的构造函数即Nevermore60Customer 类的默认构造函数,默认Nevermore60Customer 构造函数首先要做的是为其直接基类GenericCustomer运行默认构造函数,然后GenericCustomer构造函数为其直接基类System.Object运行默认构造函数。而System.Object没有任何基类,所以它的默认构造函数直接执行;接着执行GenericCustomer的默认构造函数,将name字段初始化为null;最后执行Nevermore60Customer的默认构造函数,将highCostMinutesUsed字段初始化未0,并退出。

    abstract class GenericCustomer
    {
        private string name;        
    }

    class Nevermore60Customer : GenericCustomer
    {
        private uint highCostMinutesUsed;
    }

2.基类定义了一个无参构造函数

       执行GenericCustomer customer = new Nevermore60Customer();语句,构造函数执行顺序:System.Object类的默认构造函数=》GenericCustomer类的显示无参构造函数(将name字段初始化为“<no name>”)=》Nevermore60Customer类的默认无参构造函数(将highCostMinutesUsed字段初始化为0)。

    abstract class GenericCustomer
    {
        private string name;
        
        public GenericCustomer()
            :base() //base,调用基类的构造函数(本例中调用System.Object中的构造函数,与默认情况相同,可省略)
        {
            name = "<no name>";
        }
    }

    class Nevermore60Customer : GenericCustomer
    {
        private uint highCostMinutesUsed;
    }

      注意:若把GenericCustomer类中的构造函数声明为private,则类Nevermore60Customer会产生一个编译错误。因为编译器试图为Nevermore60Customer类生成默认构造函数时,需要调用类GenericCustomer的无参构造函数,但是这个函数是类GenericCustomer所私有的,其他类无法调用。

           

3.基类和派生类都定义了有参构造函数

       执行GenericCustomer customer = new Nevermore60Customer("LiSi");语句时,构造函数执行顺序:System.Object类的默认构造函数=》GenericCustomer类的有参构造函数(将name字段初始化为“LiSi”)=》Nevermore60Customer类的有参构造函数(什么也不做)。

    abstract class GenericCustomer
    {
        private string name;
        
        public GenericCustomer(string name)
        {
            this.name = name;
        }        
    }

    class Nevermore60Customer : GenericCustomer
    {
        private uint highCostMinutesUsed;

        public Nevermore60Customer(string name)
            :base(name)
        {

        }
    }

         注意:若类Nevermore60Customer未定义上面的有参构造函数,则类Nevermore60Customer会产生一个编译错误。因为类Nevermore60Customer生成的默认构造函数会试图调用GenericCustomer类中的无参构造函数,但它并没有这样的函数。

                    

4.派生类中有多个构造函数

           执行GenericCustomer customer = new Nevermore60Customer("LiSi");语句时,构造函数执行顺序:System.Object类的默认构造函数=》GenericCustomer类的有参构造函数(将name字段初始化为“LiSi”)=》Nevermore60Customer类中有两个参数的构造函数(将referrerName字段初始化为“None”)=》Nevermore60Customer类中有一个参数的构造函数(什么也不做)

    abstract class GenericCustomer
    {
        private string name;

        public GenericCustomer(string name)
        {
            this.name = name;
        }
    }

    class Nevermore60Customer : GenericCustomer
    {
        private uint highCostMinutesUsed;

        private string referrerName;

        public Nevermore60Customer(string name, string referrerName)
            : base(name)
        {
            this.referrerName = referrerName;
        }

        public Nevermore60Customer(string name)
            : this(name, "<None>")
        {

        }
    }

 

参考来源:《C#高级编程(第9版)》

posted on 2018-02-02 16:21  雪溪  阅读(2140)  评论(0编辑  收藏  举报