構(gòu)造函數(shù)的調(diào)用順序是先調(diào)用System.Object,再按照層次結(jié)構(gòu)由上向下(基類=》派生類)進(jìn)行,直到到達(dá)編譯器要實例化的類為止。在此過程中,每個構(gòu)造函數(shù)都初始化自己類中的字段。編譯器先自下而上查找構(gòu)造函數(shù),然后再自上而下地執(zhí)行。
以下通過示例說明派生類的構(gòu)造函數(shù)是如何執(zhí)行的。
1.基類和派生類都未顯示定義構(gòu)造函數(shù)
執(zhí)行GenericCustomer customer = new Nevermore60Customer();語句時,編譯器首先找到試圖實例化的類的構(gòu)造函數(shù)即Nevermore60Customer 類的默認(rèn)構(gòu)造函數(shù),默認(rèn)Nevermore60Customer 構(gòu)造函數(shù)首先要做的是為其直接基類GenericCustomer運行默認(rèn)構(gòu)造函數(shù),然后GenericCustomer構(gòu)造函數(shù)為其直接基類System.Object運行默認(rèn)構(gòu)造函數(shù)。而System.Object沒有任何基類,所以它的默認(rèn)構(gòu)造函數(shù)直接執(zhí)行;接著執(zhí)行GenericCustomer的默認(rèn)構(gòu)造函數(shù),將name字段初始化為null;最后執(zhí)行Nevermore60Customer的默認(rèn)構(gòu)造函數(shù),將highCostMinutesUsed字段初始化未0,并退出。
abstract class GenericCustomer { private string name; } class Nevermore60Customer : GenericCustomer { private uint highCostMinutesUsed; }
2.基類定義了一個無參構(gòu)造函數(shù)
執(zhí)行GenericCustomer customer = new Nevermore60Customer();語句,構(gòu)造函數(shù)執(zhí)行順序:System.Object類的默認(rèn)構(gòu)造函數(shù)=》GenericCustomer類的顯示無參構(gòu)造函數(shù)(將name字段初始化為“<no name>”)=》Nevermore60Customer類的默認(rèn)無參構(gòu)造函數(shù)(將highCostMinutesUsed字段初始化為0)。
abstract class GenericCustomer { private string name; public GenericCustomer() :base() //base,調(diào)用基類的構(gòu)造函數(shù)(本例中調(diào)用System.Object中的構(gòu)造函數(shù),與默認(rèn)情況相同,可省略) { name = "<no name>"; } } class Nevermore60Customer : GenericCustomer { private uint highCostMinutesUsed; }
注意:若把GenericCustomer類中的構(gòu)造函數(shù)聲明為private,則類Nevermore60Customer會產(chǎn)生一個編譯錯誤。因為編譯器試圖為Nevermore60Customer類生成默認(rèn)構(gòu)造函數(shù)時,需要調(diào)用類GenericCustomer的無參構(gòu)造函數(shù),但是這個函數(shù)是類GenericCustomer所私有的,其他類無法調(diào)用。

3.基類和派生類都定義了有參構(gòu)造函數(shù)
執(zhí)行GenericCustomer customer = new Nevermore60Customer("LiSi");語句時,構(gòu)造函數(shù)執(zhí)行順序:System.Object類的默認(rèn)構(gòu)造函數(shù)=》GenericCustomer類的有參構(gòu)造函數(shù)(將name字段初始化為“LiSi”)=》Nevermore60Customer類的有參構(gòu)造函數(shù)(什么也不做)。
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未定義上面的有參構(gòu)造函數(shù),則類Nevermore60Customer會產(chǎn)生一個編譯錯誤。因為類Nevermore60Customer生成的默認(rèn)構(gòu)造函數(shù)會試圖調(diào)用GenericCustomer類中的無參構(gòu)造函數(shù),但它并沒有這樣的函數(shù)。

4.派生類中有多個構(gòu)造函數(shù)
執(zhí)行GenericCustomer customer = new Nevermore60Customer("LiSi");語句時,構(gòu)造函數(shù)執(zhí)行順序:System.Object類的默認(rèn)構(gòu)造函數(shù)=》GenericCustomer類的有參構(gòu)造函數(shù)(將name字段初始化為“LiSi”)=》Nevermore60Customer類中有兩個參數(shù)的構(gòu)造函數(shù)(將referrerName字段初始化為“None”)=》Nevermore60Customer類中有一個參數(shù)的構(gòu)造函數(shù)(什么也不做)
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版)》
浙公網(wǎng)安備 33010602011771號