默認構造函數,如果沒有為類指定任何構造函數,編譯器會自動為類創建一個無參構造函數,用以初始化類的字段;如果為類編寫了構造函數,那么編譯器就不會再自動生成無參構造函數了。ps.C#不允許用戶為結構定義無參構造函數。
靜態構造函數,不能訪問實例成員,只能用來初始化一些靜態字段或者屬性,僅在第一次調用類的任何成員時自動執行,不帶訪問修飾符,不帶任何參數,每個類只能有一個靜態構造函數,但可以同時還有一個無參實例構造函數,如下。
public class Demo { static Demo() { } public Demo() { } }
私有構造函數,將構造函數申明為私有的,則不能通過new運算符在外部代碼中實例化(但可以編寫一個靜態方法或屬性在其內部實例化一個對象,再將結果返回給外部代碼)。私有構造函數的作用:
- 永遠不會實例化,因為它僅用作某些靜態成員的容器
- 希望類只能通過調用某個靜態方法來實例化(即所謂的對象實例化的類工廠方法)
public class Demo { private Demo() { } public static Demo NewDemo() { return new Demo(); } }
構造函數執行順序,通常情況下:構造函數先調用System.Object的構造函數,再按照繼承的層次結構從上往下進行,直到最終要實例化的類為止,即最先調用的是基類的構造函數,但如果類有靜態構造函數,且為首次調用該類,則先調用的是子類的靜態構造函數,再是父類的靜態構造函數,當然靜態構造函數只會執行這一次,如下
//父類 public class SuperClass { static SuperClass() { Console.WriteLine("Super.Static"); } public SuperClass() { Console.WriteLine("Super.Instance"); } } //子類 public class ChildClass : SuperClass { static ChildClass() { Console.WriteLine("Child.Static"); } public ChildClass() { Console.WriteLine("Child.Instance"); } } //客戶程序 class Program { static void Main(string[] args) { ChildClass cc = new ChildClass(); Console.ReadKey(); } }
輸出結果為:
Child.Static
Super.Static
Super.Instance
Child.Instance
在不考了靜態構造函數的情況下(因為靜態構造僅執行一次,且定義靜態構造函數的時候並不多),子類在調用父類的構造函數時,默認情況是調用父類的無參構造函數,如果父類只有帶參構造函數,而沒有無參構造函數,那么編譯時會報錯;不過我們可以通過base關鍵字來指定調用帶參構造函數,如下
//父類 public class SuperClass { public SuperClass(string param) { Console.WriteLine("Super:" + param); } } //子類 public class ChildClass : SuperClass { public ChildClass(string param):base(param) { Console.WriteLine("Child:" + param); } } //客戶程序 class Program { static void Main(string[] args) { ChildClass cc = new ChildClass("param"); Console.ReadKey(); } }
輸出結果為
Super:param
Child:param