詳解C#編程中構(gòu)造函數(shù)的使用
當類或結(jié)構(gòu)創(chuàng)建時,其構(gòu)造函數(shù)調(diào)用。構(gòu)造函數(shù)與選件類或結(jié)構(gòu)相同,并且,它們通常用于初始化新對象的數(shù)據(jù)成員。
在下面的示例中,使用一個簡單的構(gòu)造函數(shù)定義了名為 Taxi 的類。然后使用 new 運算符來實例化該類。在為新對象分配內(nèi)存之后,new 運算符立即調(diào)用 Taxi 構(gòu)造函數(shù)。
public class Taxi { public bool isInitialized; public Taxi() { isInitialized = true; } } class TestTaxi { static void Main() { Taxi t = new Taxi(); Console.WriteLine(t.isInitialized); } }
不帶參數(shù)的構(gòu)造函數(shù)稱為“默認構(gòu)造函數(shù)”。無論何時,只要使用 new 運算符實例化對象,并且不為 new 提供任何參數(shù),就會調(diào)用默認構(gòu)造函數(shù)。
除非類是 static 的,否則 C# 編譯器將為無構(gòu)造函數(shù)的類提供一個公共的默認構(gòu)造函數(shù),以便該類可以實例化。
通過將構(gòu)造函數(shù)設(shè)置為私有構(gòu)造函數(shù),可以阻止類被實例化,如下所示:
class NLog { // Private Constructor: private NLog() { } public static double e = Math.E; //2.71828... }
結(jié)構(gòu)類型的構(gòu)造函數(shù)與類的構(gòu)造函數(shù)類似,但是 structs 不能包含顯式默認構(gòu)造函數(shù),因為編譯器將自動提供一個構(gòu)造函數(shù)。此構(gòu)造函數(shù)會將 struct 中的每個字段初始化為默認值。然而,只有當 struct 用 new 實例化時,才會調(diào)用此默認構(gòu)造函數(shù)。例如,下面的代碼使用 Int32 的默認構(gòu)造函數(shù),因此您可以確信整數(shù)已初始化:
int i = new int(); Console.WriteLine(i);
不過,下面的代碼卻會導致編譯器錯誤,因為它沒有使用 new,而且嘗試使用尚未初始化的對象:
int i; Console.WriteLine(i);
或者,基于 structs 的對象(包括所有內(nèi)置數(shù)值類型)可以初始化或賦值后使用,如下面的示例所示:
int a = 44; // Initialize the value type... int b; b = 33; // Or assign it before using it. Console.WriteLine("{0}, {1}", a, b);
因此對值類型調(diào)用默認構(gòu)造函數(shù)不是必需的。
類和 structs 都可以定義具有參數(shù)的構(gòu)造函數(shù)。帶參數(shù)的構(gòu)造函數(shù)必須通過 new 語句或 base 語句來調(diào)用。類和 structs 還可以定義多個構(gòu)造函數(shù),并且二者均不需要定義默認構(gòu)造函數(shù)。例如:
public class Employee { public int salary; public Employee(int annualSalary) { salary = annualSalary; } public Employee(int weeklySalary, int numberOfWeeks) { salary = weeklySalary * numberOfWeeks; } }
可以使用下列語句中的任一個語句來創(chuàng)建此類:
Employee e1 = new Employee(30000); Employee e2 = new Employee(500, 52);
構(gòu)造函數(shù)可以使用 base 關(guān)鍵字來調(diào)用基類的構(gòu)造函數(shù)。例如:
public class Manager : Employee { public Manager(int annualSalary) : base(annualSalary) { //Add further instructions here. } }
在此示例中,基類的構(gòu)造函數(shù)在執(zhí)行構(gòu)造函數(shù)塊之前被調(diào)用。 base 關(guān)鍵字可帶參數(shù)使用,也可不帶參數(shù)使用。構(gòu)造函數(shù)的任何參數(shù)都可用作 base 的參數(shù),或用作表達式的一部分。有關(guān)更多信息,請參見base(C# 參考)。
在派生類中,如果不使用 base 關(guān)鍵字來顯式調(diào)用基類構(gòu)造函數(shù),則將隱式調(diào)用默認構(gòu)造函數(shù)(如果有的話)。這意味著下面的構(gòu)造函數(shù)聲明在效果上是相同的:
public Manager(int initialdata) { //Add further instructions here. } public Manager(int initialdata) : base() { //Add further instructions here. }
如果基類沒有提供默認構(gòu)造函數(shù),派生類必須使用 base 顯式調(diào)用基構(gòu)造函數(shù)。
構(gòu)造函數(shù)可以使用 this 關(guān)鍵字調(diào)用同一對象中的另一構(gòu)造函數(shù)。和 base 一樣,this 可帶參數(shù)使用也可不帶參數(shù)使用,構(gòu)造函數(shù)中的任何參數(shù)都可用作 this 的參數(shù),或者用作表達式的一部分。例如,可以使用 this 重寫前一示例中的第二個構(gòu)造函數(shù):
public Employee(int weeklySalary, int numberOfWeeks) : this(weeklySalary * numberOfWeeks) { }
上一示例中對 this 關(guān)鍵字的使用導致此構(gòu)造函數(shù)被調(diào)用:
public Employee(int annualSalary) { salary = annualSalary; }
構(gòu)造函數(shù)可以標記為 public、private、protected、internal 或 protectedinternal。這些訪問修飾符定義類的用戶構(gòu)造該類的方式。有關(guān)更多信息,請參見訪問修飾符。
實例構(gòu)造函數(shù)
使用 new 表達式創(chuàng)建某個類的對象時,會使用實例構(gòu)造函數(shù)創(chuàng)建和初始化所有實例成員變量。要初始化靜態(tài)類或非靜態(tài)類中的靜態(tài)變量,必須定義靜態(tài)構(gòu)造函數(shù)。
下面的示例演示實例構(gòu)造函數(shù):
class CoOrds { public int x, y; // constructor public CoOrds() { x = 0; y = 0; } }
注意
為了清楚起見,此類包含公共字段。建議在編程時不要使用公共字段,因為這種做法會使程序中任何位置的任何方法都可以不受限制、不經(jīng)驗證地訪問對象的內(nèi)部組件。數(shù)據(jù)成員通常應當為私有的,并且只應當通過類方法和屬性來訪問。
只要創(chuàng)建基于 CoOrds 類的對象,就會調(diào)用此實例構(gòu)造函數(shù)。諸如此類不帶參數(shù)的構(gòu)造函數(shù)稱為“默認構(gòu)造函數(shù)”。然而,提供其他構(gòu)造函數(shù)通常十分有用。例如,可以向 CoOrds 類添加構(gòu)造函數(shù),以便可以為數(shù)據(jù)成員指定初始值:
// A constructor with two arguments: public CoOrds(int x, int y) { this.x = x; this.y = y; }
這樣便可以用默認或特定的初始值創(chuàng)建 CoOrd 對象,如下所示:
CoOrds p1 = new CoOrds(); CoOrds p2 = new CoOrds(5, 3);
如果某個類沒有構(gòu)造函數(shù),則會自動生成一個默認構(gòu)造函數(shù),并使用默認值來初始化對象字段。例如,int 初始化為 0。有關(guān)默認值的更多信息,請參見 默認值表(C# 參考)。因此,由于 CoOrds 類的默認構(gòu)造函數(shù)將所有數(shù)據(jù)成員都初始化為零,因此可以將它完全移除,而不會更改類的工作方式。本主題的稍后部分的示例 1 中提供了使用多個構(gòu)造函數(shù)的完整示例,示例 2 中提供了自動生成的構(gòu)造函數(shù)的示例。
也可以用實例構(gòu)造函數(shù)來調(diào)用基類的實例構(gòu)造函數(shù)。類構(gòu)造函數(shù)可通過初始值設(shè)定項來調(diào)用基類的構(gòu)造函數(shù),如下所示:
class Circle : Shape { public Circle(double radius) : base(radius, 0) { } }
在此示例中,Circle 類將表示半徑和高度的值傳遞給 Shape(Circle 從它派生而來)提供的構(gòu)造函數(shù)。使用 Shape 和 Circle 的完整示例請見本主題中的示例 3。
示例 1
下面的示例說明包含兩個類構(gòu)造函數(shù)的類:一個類構(gòu)造函數(shù)沒有參數(shù),另一個類構(gòu)造函數(shù)帶有兩個參數(shù)。
class CoOrds { public int x, y; // Default constructor: public CoOrds() { x = 0; y = 0; } // A constructor with two arguments: public CoOrds(int x, int y) { this.x = x; this.y = y; } // Override the ToString method: public override string ToString() { return (String.Format("({0},{1})", x, y)); } } class MainClass { static void Main() { CoOrds p1 = new CoOrds(); CoOrds p2 = new CoOrds(5, 3); // Display the results using the overriden ToString method: Console.WriteLine("CoOrds #1 at {0}", p1); Console.WriteLine("CoOrds #2 at {0}", p2); Console.ReadKey(); } }
輸出:
CoOrds #1 at (0,0) CoOrds #2 at (5,3)
示例 2
在此示例中,類 Person 沒有任何構(gòu)造函數(shù);在這種情況下,將自動提供默認構(gòu)造函數(shù),同時將字段初始化為它們的默認值。
public class Person { public int age; public string name; } class TestPerson { static void Main() { Person person = new Person(); Console.WriteLine("Name: {0}, Age: {1}", person.name, person.age); // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); } }
輸出:
Name: , Age: 0
注意,age 的默認值為 0,name 的默認值為 null。有關(guān)默認值的更多信息,請參見 默認值表(C# 參考)。
示例 3
下面的示例說明使用基類初始值設(shè)定項。 Circle 類是從通用類 Shape 派生的,Cylinder 類是從 Circle 類派生的。每個派生類的構(gòu)造函數(shù)都使用其基類的初始值設(shè)定項。
abstract class Shape { public const double pi = Math.PI; protected double x, y; public Shape(double x, double y) { this.x = x; this.y = y; } public abstract double Area(); } class Circle : Shape { public Circle(double radius) : base(radius, 0) { } public override double Area() { return pi * x * x; } } class Cylinder : Circle { public Cylinder(double radius, double height) : base(radius) { y = height; } public override double Area() { return (2 * base.Area()) + (2 * pi * x * y); } } class TestShapes { static void Main() { double radius = 2.5; double height = 3.0; Circle ring = new Circle(radius); Cylinder tube = new Cylinder(radius, height); Console.WriteLine("Area of the circle = {0:F2}", ring.Area()); Console.WriteLine("Area of the cylinder = {0:F2}", tube.Area()); // Keep the console window open in debug mode. Console.WriteLine("Press any key to exit."); Console.ReadKey(); } }
輸出:
Area of the circle = 19.63 Area of the cylinder = 86.39
上一篇:理解C#編程中的靜態(tài)類和靜態(tài)成員以及密封類
欄 目:C#教程
下一篇:詳解C#中的屬性和屬性的使用
本文地址:http://mengdiqiu.com.cn/a1/C_jiaocheng/6741.html
您可能感興趣的文章
- 01-10C#通過反射獲取當前工程中所有窗體并打開的方法
- 01-10C#實現(xiàn)Winform中打開網(wǎng)頁頁面的方法
- 01-10C#實現(xiàn)由四周向中心縮小的窗體退出特效
- 01-10Extjs4如何處理后臺json數(shù)據(jù)中日期和時間
- 01-10C#編程實現(xiàn)自定義熱鍵的方法
- 01-10C#中DataGridView常用操作實例小結(jié)
- 01-10C#編程獲取資源文件中圖片的方法
- 01-10asp.net中XML如何做增刪改查操作
- 01-10C#利用反射技術(shù)實現(xiàn)去掉按鈕選中時的邊框效果
- 01-10C#中查找Dictionary中的重復值的方法


閱讀排行
本欄相關(guān)
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻 器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 04-02jquery與jsp,用jquery
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實例總結(jié)
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-11ajax實現(xiàn)頁面的局部加載
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢dedecms什么時候用欄目交叉功能?