C#構(gòu)造函數(shù)的運(yùn)用淺析
C#構(gòu)造函數(shù)的名字不能隨便起,必須讓編譯器認(rèn)得出才可以被自動(dòng)執(zhí)行。它的命名方法既簡(jiǎn)單又合理:讓C#構(gòu)造函數(shù)與類同名。除了名字外,C#構(gòu)造函數(shù)的另一個(gè)特別之處是沒(méi)有返回值類型,這與返回值類型為void的函數(shù)不同。如果它有返回值類型,那么編譯器將不知所措。在你可以訪問(wèn)一個(gè)類的方法、屬性或任何其它東西之前, ***條執(zhí)行的語(yǔ)句是包含有相應(yīng)類的C#構(gòu)造函數(shù)。甚至你自己不寫(xiě)一個(gè)C#構(gòu)造函數(shù),也會(huì)有一個(gè)缺省C#構(gòu)造函數(shù)提供給你。
- class TestClass
- {
- public TestClass(): base() {} // 由CLR提供
- }
下面列舉了幾種類型的C#構(gòu)造函數(shù)
1)缺省C#構(gòu)造函數(shù)
- class TestClass
- {
- public TestClass(): base() {}
- }
上面已介紹,它由系統(tǒng)(CLR)提供。
2)實(shí)例C#構(gòu)造函數(shù)
實(shí)例C#構(gòu)造函數(shù)是實(shí)現(xiàn)對(duì)類中實(shí)例進(jìn)行初始化的方法成員。如:
- using System;
- class Point
- {
- public double x, y;
- public Point()
- {
- this.x = 0;
- this.y = 0;
- }
- public Point(double x, double y)
- {
- this.x = x;
- this.y = y;
- }
- …
- }
- class Test
- {
- static void Main()
- {
- Point a = new Point();
- Point b = new Point(3, 4); // 用C#構(gòu)造函數(shù)初始化對(duì)象
- …
- }
- }
聲明了一個(gè)類Point,它提供了兩個(gè)C#構(gòu)造函數(shù)。它們是重載的。一個(gè)是沒(méi)有參數(shù)的PointC#構(gòu)造函數(shù)和一個(gè)是有兩個(gè)double參數(shù)的PointC#構(gòu)造函數(shù)。如果類中沒(méi)有提供這些C#構(gòu)造函數(shù),那么會(huì)CLR會(huì)自動(dòng)提供一個(gè)缺省C#構(gòu)造函數(shù)的。但一旦類中提供了自定義的C#構(gòu)造函數(shù),如Point()和Point(double x, double y),則缺省C#構(gòu)造函數(shù)將不會(huì)被提供,這一點(diǎn)要注意。
3) 靜態(tài)C#構(gòu)造函數(shù)
靜態(tài)C#構(gòu)造函數(shù)是實(shí)現(xiàn)對(duì)一個(gè)類進(jìn)行初始化的方法成員。它一般用于對(duì)靜態(tài)數(shù)據(jù)的初始化。靜態(tài)C#構(gòu)造函數(shù)不能有參數(shù),不能有修飾符而且不能被調(diào)用,當(dāng)類被加載時(shí),類的靜態(tài)C#構(gòu)造函數(shù)自動(dòng)被調(diào)用。如:
- using System.Data;
- class Employee
- {
- private static DataSet ds;
- static Employee()
- {
- ds = new DataSet(...);
- }
- ...
- }
聲明了一個(gè)有靜態(tài)C#構(gòu)造函數(shù)的類Employee。注意靜態(tài)C#構(gòu)造函數(shù)只能對(duì)靜態(tài)數(shù)據(jù)成員進(jìn)行初始化,而不能對(duì)非靜態(tài)數(shù)據(jù)成員進(jìn)行初始化。但是,非靜態(tài)C#構(gòu)造函數(shù)既可以對(duì)靜態(tài)數(shù)據(jù)成員賦值,也可以對(duì)非靜態(tài)數(shù)據(jù)成員進(jìn)行初始化。
如果類僅包含靜態(tài)成員,你可以創(chuàng)建一個(gè)private的C#構(gòu)造函數(shù):private TestClass() {…},但是private意味著從類的外面不可能訪問(wèn)該C#構(gòu)造函數(shù)。所以,它不能被調(diào)用,且沒(méi)有對(duì)象可以被該類定義實(shí)例化。
以上是幾種類型C#構(gòu)造函數(shù)的簡(jiǎn)單運(yùn)用,下面將重點(diǎn)介紹一下在類的層次結(jié)構(gòu)中(即繼承結(jié)構(gòu)中)基類和派生類的C#構(gòu)造函數(shù)的使用方式。派生類對(duì)象的初始化由基類和派生類共同完成:基類的成員由基類的C#構(gòu)造函數(shù)初始化,派生類的成員由派生類的C#構(gòu)造函數(shù)初始化。
當(dāng)創(chuàng)建派生類的對(duì)象時(shí),系統(tǒng)將會(huì)調(diào)用基類的C#構(gòu)造函數(shù)和派生類的C#構(gòu)造函數(shù),構(gòu) 造函數(shù)的執(zhí)行次序是:先執(zhí)行基類的C#構(gòu)造函數(shù),再執(zhí)行派生類的C#構(gòu)造函數(shù)。如果派生類又有對(duì)象成員,則,先執(zhí)行基類的C#構(gòu)造函數(shù),再執(zhí)行成員對(duì)象類的C#構(gòu)造函數(shù),***執(zhí)行派生類的C#構(gòu)造函數(shù)。
至于執(zhí)行基類的什么C#構(gòu)造函數(shù),缺省情況下是執(zhí)行基類的無(wú)參C#構(gòu)造函數(shù),如果要執(zhí)行基類的有參C#構(gòu)造函數(shù),則必須在派生類C#構(gòu)造函數(shù)的成員初始化表中指出。如:
- class A
- { private int x;
- public A( ) { x = 0; }
- public A( int i ) { x = i; }
- };
- class B : A
- { private int y;
- public B( ) { y = 0; }
- public B( int i ) { y = i; }
- public B( int i, int j ):A(i) { y = j; }
- };
- B b1 = new B();
- //執(zhí)行基類A的C#構(gòu)造函數(shù)A(),再執(zhí)行派生類的C#構(gòu)造函數(shù)B()
- B b2 = new B(1);
- //執(zhí)行基類A的C#構(gòu)造函數(shù)A(),再執(zhí)行派生類的C#構(gòu)造函數(shù)B(int)
- B b3 = new B(0,1);
- //執(zhí)行執(zhí)行基類A的C#構(gòu)造函數(shù)A(int) ,再執(zhí)行派生類的
C#構(gòu)造函數(shù)B(int,int)
在這里C#構(gòu)造函數(shù)的執(zhí)行次序是一定要分析清楚的。另外,如果基類A中沒(méi)有提供無(wú)參C#構(gòu)造函數(shù)public A( ) { x = 0; },則在派生類的所有C#構(gòu)造函數(shù)成員初始化表中必須指出基類A的有參C#構(gòu)造函數(shù)A(i),如下所示:
- class A
- { private int x;
- public A( int i ) { x = i; }
- };
- class B : A
- { private int y;
- public B():A(i) { y = 0; }
- public B(int i):A(i) { y = i; }
- public B(int i, int j):A(i) { y = j; }
- };
C#構(gòu)造函數(shù)的運(yùn)用就向你介紹到這里,希望對(duì)你學(xué)習(xí)C#構(gòu)造函數(shù)的運(yùn)用有所幫助。
【編輯推薦】