C#派生類的構造函數


      構造函數的調用順序是先調用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版)》


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM