第五講 構造器與析構器
構造器
構造器負責類中成員變量(域)的初始化。C#的類有兩種構造器:實例構造器和靜態構造器。實例構造器負責初始化類中的實例變量,它只有在用戶用new關鍵字為對象分配內存時才被調用。而且作為引用類型的類,其實例化後的對象必然是分配在托管堆(Managed Heap)上。這裡的托管的意思是指該內存受.NET的CLR運行時管理。和C++不同的是,C#中的對象不可以分配在棧中,用戶只聲明對象是不會產生構造器調用的。
實例構造器分為缺省構造器和非缺省構造器。缺省構造器是在一個類沒有聲明任何構造器的情況下,編譯器強制為該類添加的一個無參數的構造器,該構造器僅僅調用父類的無參數構造器。缺省構造器實際上是C#編譯器為保證每一個類都有至少一個構造器而采取的附加規則。注意這裡的三個要點:
子類沒有聲明任何構造器;
編譯器為子類加的缺省構造器一定為無參數的構造器;
父類一定要存在一個無參數的構造器。
看下面例子的輸出:
using System; public class MyClass1 { public MyClass1() { Console.WriteLine(“MyClass1 Parameterless Contructor!”); } public MyClass1(string param1) { Console.WriteLine(“MyClass1 Constructor Parameters : ”+param1); } } public class MyClass2:MyClass1 { } public class Test { public static void Main() { MyClass2 myobject1=new MyClass2(); } }
編譯程序並運行可以得到下面的輸出:
MyClass1 Parameterless Contructor!
讀者可以去掉MyClass1的無參構造器public MyClass1()看看編譯結果。
構造器在繼承時需要特別的注意,為了保證父類成員變量的正確初始化,子類的任何構造器默認的都必須調用父類的某一構造器,具體調用哪個構造器要看構造器的初始化參數列表。如果沒有初始化參數列表,那麼子類的該構造器就調用父類的無參數構造器;如果有初始化參數列表,那麼子類的該構造器就調用父類對應的參數構造器。看下面例子的輸出:
using System; public class MyClass1 { public MyClass1() { Console.WriteLine("MyClass1 Parameterless Contructor!"); } public MyClass1(string param1) { Console.WriteLine("MyClass1 Constructor Parameters : "+param1); } } public class MyClass2:MyClass1 { public MyClass2(string param1):base(param1) { Console.WriteLine("MyClass2 Constructor Parameters : "+param1); } } public class Test { public static void Main() { MyClass2 myobject1=new MyClass2("Hello"); } }
編譯程序並運行可以得到下面的輸出:
MyClass1 Constructor Parameters : Hello MyClass2 Constructor Parameters : HelloC#支持變量的聲明初始化。類內的成員變量聲明初始化被編譯器轉換成賦值語句強加在類的每一個構造器的內部。那麼初始化語句與調用父類構造器的語句的順序是什麼呢?看下面例子的輸出:
using System; public class MyClass1 { public MyClass1() { Print(); } public virtual void Print() {} } public class MyClass2: MyClass1 { int x = 1; int y; public MyClass2() { y = -1; Print(); } public override void Print() { Console.WriteLine("x = {0}, y = {1}", x, y); } } public class Test { static void Main() { MyClass2 MyObject1 = new MyClass2(); } }
編譯程序並運行可以得到下面的輸出: