天天看點

黑馬程式員_類

------- Windows Phone 7手機開發、.Net教育訓練、期待與您交流! ------- 

為了便于複雜程式開發,開發人員将資料和與之相關的運算打包到一起,統一考慮,進而形成了類。類實際就是資料和相關處理的代碼的封裝體。它也構成了面向對象程式設計的核心。

類的概念

類(class)是一種資料結構,它可以包含資料成員、函數成員和嵌套類型。

類支援繼承,繼承是一種機制,它使派生類可以對基類進行擴充和專用化。C#應用程式一般是由程式設計者自定義的類和.NET Framework的類組成。

類聲明

類和變量一樣,在使用之前必須聲明。聲明類需要使用class關鍵字

聲明名稱為Program的類。

public class Program            //聲明類Program

{   

}

類的通路權限

不同的類需要有不同的通路權限,是以使用類修飾符來限定類。C#用多種修飾符來表達類的不同性質。類修飾符放在class關鍵字的前面,它包括new、public、protected、internal、private、abstract和sealed 7個關鍵字。其中,public、protected、internal和private修飾符控制類的可通路性。

它們的意義具體說明如下:

public修飾符表示該類是公開的,通路不受限制。

protected修飾符表示該類隻能是本身或其派生的類通路。

internal修飾符表示該類隻能是在目前應用程式中通路。

private修飾符表示該類隻能是本身通路。

abstract修飾符指定類為抽象類;

sealed修飾符指定類為密封類,即它不能被繼承。

聲明一個名稱為Test的抽象類,并在該類中聲明一個名稱為Function()的抽象方法。

abstract class Test           //聲明抽象類Test

{   

      abstract public void Function();                  

     //抽象方法,方法不包括具體實作

}

注意:抽象類不能被執行個體化,它一般作為其他類的基類,也不能被密封。

聲明一個名稱為Class1的密封類,并在該類中聲明一個名稱為Fun()的方法。

sealed class Class1                 //聲明密封類Class1

{   

      public void Fun()

            {

            }             //方法

}

注意:密封類不能作為基類,也不能作為抽象類。是以,不能從密封類派生新的類。

new修飾符

在繼承關系中,如果子類和父類擁有同名的方法,編譯器會發出警告。為了避免這種警告,需要在子類定義該方法的時候,使用new進行修飾。

new修飾符用于顯式隐藏從基類繼承的成員,并用派生類的方法替換基類的方法。如果在不是繼承類聲明中使用new修飾符,則會生成警告。

聲明兩個類:Class1和Class2。其中,Class2類是Class1類的派生類。Class1類和Class2類都聲明一個名稱x的靜态字段,并且Class2類使用new修飾符有意隐藏繼承的靜态字段x。

public class Class1

{

     public static int x = 55;

     public static int  y=22;

}

public class Class2 : Class1

{

     new public static int x = 100;   //使用 new 修飾符聲明一個靜态字段

     static void Main()

    {

          Console.WriteLine(x);   // Class2類中的x

          Console.WriteLine("Class1="+Class1.x);

          Console.WriteLine(y);

          Console.WriteLine();

    }

}

繼承類

在程式開發中,有一些類是通用的。就像學生類、教師類,都是基于人這個類,都有姓名、性别、年齡這些成員。通過使用繼承可以建立通用類,該類定義一組相關對象所共有的特征。然後,該類可以被其他更具體的類繼承,再添加一些特有的成員。類類型支援繼承(inherit)。繼承是一種機制,它使派生類可以對基類進行擴充和專用化。即一個類可以從另外一個類繼承而來。

聲明兩個類:Class1和Class2類。其中,Class2類從Class1類直接繼承而來,Class1類被稱為Class2類的直接基類,Class2類為Class1類的派生類。

public class Class1 

{

     public void F() { }                     //Class1類的方法

}

public class Class2 : Class1             //繼承于Class1類,包括它的成員

{

}

Class2類繼承于Class1類,即隐式地把Class1類的成員也當作自己的成員(除了Class1類的構造函數和析構函數之外)。是以,Class2類的成員也包括F()方法。

類繼承具有以下5個特點。

繼承是可傳遞的。如果C類從B類派生,而B類從A類派生,那麼C類就會既繼承在B類中聲明的成員,又繼承在A類中聲明的成員(除了A類的構造函數和析構函數之外)。

繼承是可擴充的。派生類能夠擴充它的直接基類,而且能夠添加新的成員,但是不能移除繼承成員的定義。

基類成員可隐藏。派生類可以通過聲明具有相同名稱或簽名的新成員來隐藏那個被繼承的成員(使用new修飾符)。

父類與子類類型可轉換。存在一個從派生類類型到它的任一基類類型的隐式轉換。

子類可重載父類的成員。類可以聲明虛的方法、屬性和索引器,而派生類可以重寫這些函數成員的實作。這種特征被稱為類的“多态性行為”特征。

類、對象和執行個體化

類是從對象抽象出來的。要實作重用,必須由類建構出對應的對象。這個過程稱為執行個體化。執行個體化是一種操作,它可以為類的執行個體配置設定記憶體。

聲明名稱為Program的類,并建立Program類的一個執行個體p,然後使用new操作為p執行個體化。

public class Program         //定義一個公有類Program

{

}

Program p;                      //定義一個類Program的對象p

p = new Program();            //将類Program的對象p執行個體化

“public class Program{…}”代碼聲明名稱為Program的類,即Program是一個類。p是Program類的一個執行個體,也稱為對象,此時,p的值為null。“p = new Program ()”表達式将p執行個體化,此時,p的值不為null,它可以被引用或通路。

類的組成

類可以包含多種成員,分為兩大類:

資料成員和函數成員。其中,資料成員包括常量和字段;

函數成員包括方法、屬性、事件、索引器、運算符、執行個體構造函數、析構函數和該類的靜态構造函數。

常量:用來表示常數值。

字段:類的變量。

方法:是包含一系列語句的代碼塊,通過這些代碼塊能夠實作預先定義的計算或操作。

事件:一種使對象或類能夠提供通知的成員。用戶端可以通過提供事件處理程式(event handler)為相應的事件添加可執行代碼。

屬性:用于通路對象或類的特性的成員。

索引器:是一種含有參數的屬性,又稱為含參屬性。它提供索引的方式來通路對象,即與數組的通路方式相同。

運算符:定義表達式運算符,通過它可以對該類的執行個體進行運算。

執行個體構造函數:不使用static修飾符,用于實作初始化該類的執行個體所需的操作。

析構函數:一種用于實作銷毀類執行個體所需操作的成員。靜态構造函數:使用static修飾符,用于實作初始化該類自身所需的操作。類型:該類的局部類型。

常量

常量(constant)是使用一個辨別符來代替一個不變的值。例如使用PI代替圓周率。

使用常量有兩個好處:

一是使程式易于維護、修改;

二是使程式的安全性更好。

常量的類型必須為sbyte、byte、short、ushort、int、uint、long、ulong、char、float、double、decimal、bool、string、枚舉類型或引用類型。

在聲明常量時,需要使用const關鍵字。但是,常量必須在定義時就指派。在定義完常量後,在後面的程式設計中就不允許對常量進行重新指派。

聲明名稱為pi的、類型為float的常量。

const float pi = 3.14f;              //聲明float型的常量pi,并為它賦初值

如果使用一個const關鍵字同時聲明多個常量,那麼常量之間需要使用,(逗号)分隔。

聲明3個類型為int的常量:i、j和k,它們的值分别為1、2和3。

const int i = 1, j = 2, k = 3;    //聲明類型為int的三個常量i,j,k,并為其賦初值

聲明了3個類型為int的常量:i、j和k,它們的值分别為1、2和3。

等價于下列語句:

const int i = 1;

const int j = 2;

const int k = 3;

如果一個常量的值依賴于其他常量的值,且這種依賴關系不是循環的,那麼編譯器會自動按照一定的順序計算所有常量的值。

聲明2個類:Class1和Class2。Class1類包括2個常量:I和J;Class2類包含一個常量:K。I常量的值依賴于K常量,K常量的值依賴于J常量。是以,編譯器在計算這3個常量的值時,首先計算J常量的值,然後計算K常量的值,最後計算I常量的值。

public class Class1

{

     public const int I = Class2.K+1;

     public const int J = 2;

}

public class Class2

{

     public const int k = Class1.J+2;

}

class Program

{

     Console.WriteLine("I+"+Class1.I);

     Console.WriteLine("J+"+Class1.J);

     Console.WriteLine("K+"+Class2.K);

     Console.WriteLine();

}

編譯器首先計算J常量的值為2,然後計算K常量的值為4,最後計算I常量的值為5。

字段

字段表示類和對象中的資料成員。它是類中的變量。

聲明2個字段:i和j。i字段沒有顯式被指派,j字段顯式被指派為20。

int i;               //聲明一個字段i

int j = 20;      //聲明一個字段j并為它賦初值20

如果在同一個語句中同時聲明多個字段,那麼字段之間需要使用,(逗号)分隔。

聲明3個類型為int的字段:i、j和k。其中,k字段的值為20。

int i,j,k = 20;                   //i和j字段的值為0,k字段的值為20

根據字段的修飾方式,可以把字段分為以下4種。

靜态字段:使用static修飾,對應于靜态變量。

執行個體字段:不使用static修飾,對應于執行個體變量。  

隻讀字段:使用readonly修飾。

易失字段:使用volatile修飾。該類型的字段很少使用。

在Program類中聲明4個類型均為int的字段:i、j、k和m。其中,i為靜态字段,它的值為20;j為執行個體字段,它的值為100;k為隻讀字段,它的值為1;m為靜态隻讀字段,它的值為15。

public class Program

{   

static int i = 20;                           //靜态字段   

int j = 100;                                  //執行個體字段   

readonly int k = 1;                          //隻讀字段   

static readonly int m = 15;                //靜态隻讀字段

}

靜态字段和執行個體字段最大的差别在于:靜态字段不屬于類的特定執行個體,而執行個體字段是屬于其所在的執行個體,如i字段不屬于Program類的某一個執行個體。當應用程式被編譯時,編譯器就會為應用程式的所有靜态字段配置設定相應的存儲位置。是以,對于一個應用程式而言,每一個靜态字段都隻有一個存儲位置。

建立Program類的2個執行個體:p1和p2。p1和p2執行個體都為j字段(為執行個體字段)配置設定各自的存儲位置。而p1和p2執行個體的i字段(為靜态字段)都引用同一個存儲位置(由編譯器決定)。

Program p1=new Program ();

Program p2=new Program ();

常量和隻讀字段最大的差别在于:常量的值在編譯時确定,而隻讀字段的值在運作時确定。如果要給隻讀字段指派,隻有在聲明該隻讀字段的語句中.k字段就在其被聲明時并指派為1

方法

方法(method)表示類和對象中的操作。它是包含一系列語句的代碼塊,通過這些代碼塊能夠實作預先定義的計算或操作。方法一般聲明在類或結構中,由通路級别、傳回值、方法名稱、方法參數和方法體組成。其中,通路級别、傳回值、方法名稱和方法參數統稱為方法的“簽名”。方法參數包括在小括弧“()”中,多個參數使用“,”(逗号)分隔。如果括弧中為空,則表示該方法不需要參數。

在Program類中聲明一個方法。該方法的簽名為“public int Function(int a,int b)”,方法名稱為Function,通路級别為public,傳回值類型為int,方法參數為“int a,int b”,方法體為緊跟該方法簽名之後的兩個“{}”之間的代碼。

class Program

{

     public int Function(int a, int b)

     {

           return a+b;

     }

     static void Main(string[] arge)

     {

            int  I=2,J=3,k;

            Program p = new program();

            k=p.Function(I,J);

            Console.WriteLine("k = "+k);

            Console.WriteLine();

     }

}

方法參數

方法參數的使用可以提高代碼的重用性。它實作的是在調用方法通過實參給方法傳遞資料,然後方法執行相應的操作,再傳回調用方。方法參數可以包含一個或多個參數。如果存在多個參數,則參數之間使用逗号分隔。方法參數包括以下4種參數。

值參數:聲明參數時不帶任何修飾符,如int i等。

引用參數:聲明參數時帶有ref修飾符,如ref int i等。

輸出參數:聲明參數時帶有out修飾符,如out int i等。

參數數組:聲明參數時帶有params修飾符,如params int[] array等。

一個值參數相當于一個局部變量,它的值來源于該方法調用時所提供的參數的值。引用參數不建立新的存儲位置,而是使用其基礎變量(作為方法參數的變量)的存儲位置。

注意:在方法被調用時,引用參數也必須添加ref關鍵字,且基礎變量必須是明确指派的。

輸出參數也不建立新的存儲位置,而是使用其基礎變量(作為方法參數的變量)的存儲位置。

注意:在方法被調用時,輸出參數也必須添加out關鍵字,且在方法傳回之前,必須為該參數明确指派。

參數數組必須為一維數組,且必須為方法的最後一個參數,它不能同時和ref或out修飾符使用。

聲明一個簽名為“public int F(int i,int j,ref int c,out int sum,params int[] args)”的方法。該方法的方法參數為“int i,int j,ref int c,out int sum,params int[] args”。i和j為值參數,c為引用參數,sum為輸出參數,args為參數數組。

public int F(int i,int j,ref int c,out int sum,params int[] args)

}

下面調用F(int i,int j,ref int c,out int sum,params int[] args)方法。i、j、c、sum和args參數的值分别為10、20、c、sum和args。其中,c和sum變量為int類型,args變量為元素類型為int的數組,且包括3個元素:1、2和3.

int c = 0,sum;

int[] args = new int[]{1,2,3};

int result = F(10,20,ref c,out sum, args);           //調用F()方法

參數數組比較特殊,它可以使用數組變量或多個元素變量直接作為它的參數來傳遞。如果變量為數組,則把該數組變量作為值參數進行傳遞。如果是多個元素變量,則為這些元素變量建立一個數組,然後将該數組作為值參數進行傳遞。是以,參數數組可以比對一個數組變量,或者由0個或1個或多個變量組成的清單。

注意:不管是數組變量,還是元素組成的清單,它們的元素類型必須能夠隐式轉換為參數數組的元素類型。

聲明一個簽名為“public int Print(params int[] args)”的方法。該方法隻包含一個參數數組args,其元素類型為int。Print(params int[] args)方法将args數組中的每一個值輸出到控制台,最後還輸出一個換行符号。然後調用Print(params int[] args)方法3次。第1次調用時使用了數組arr作為其參數,第2次調用時使用“1,2,3”作為其參數,第3次調用時未使用任何參數。

class program

{

   public static void Print(params int[] args)

   {

          Console.Write("Values");

          foreach (int i in args)

          {

               Console.WriteLine(i + " ");

          }

          Console.WriteLine();

   }

   static void Main(string[] args)

   {

       int[] arr = new arr{1,2,3};

       Print(arr);

       Print(1,2,3);

       Print();

       Console.WriteLine();

   }

}

當第1次調用時使用了arr作為其參數,它将arr數組作為值參數傳遞,是以輸出arr數組中各個元素的值。

當第2次調用時,該方法自動為這3個值建立一個元素數量為3、元素類型為int的數組,然後将該數組作為值參數傳遞。

當第3次調用時,該方法自動建立一個元素數量為空的、元素類型為int的數組,然後将該數組作為值參數傳遞。

注意:實際上,“ Print(1,2,3);  ” 等效于“ Print(new int[]{1,2,3}); ”  ,

                           “ Print();  ” 等效于“ Print(new int[]{}); ”  。

靜态方法和執行個體方法

靜态方法是類的方法,每個類也有自己的操作,靜态方法從類一建立好就開始存在。而執行個體方法是對象的方法,隻能通過對象去調用。靜态方法和執行個體方法與靜态變量和執行個體變量比較相似,靜态方法也是使用static修飾符,而執行個體方法不使用static修飾符。靜态方法屬于某一個類,執行個體方法屬于類的某一個執行個體。

下面在Program類中聲明兩個方法:F1和F2。其中,F1為靜态方法,F2為執行個體方法。然後分别調用Program類的F1和F2。在調用F1方法時,直接使用Program類調用F1方法。在調用F2方法時,首先為Program類建立一個執行個體p,然後通過p執行個體調用F2方法。

class Program

{

     public static int F1()

     {

           Console.WriteLine("調用靜态方法 F1 ");

          return 1;

     }

     public int F2()

     {

          Console.WriteLine("調用執行個體方法 F2 ");

          return 2;

     }

     static void Main(string[] args)

     {

          int r1 = new Program.F1();

          Console.WriteLine("r1 = "+r1);

          Program p = new Program();

          int r2 = p.F2();

          Console.WriteLine("r2 = "+r2);

          Console.WriteLine();

     }

}

虛方法和重寫方法

虛方法的出現是為了實作基類可以調用派生類的方法。重寫虛方法也不是必須的操作。如果派生類沒有重寫虛方法,那麼将使用基類的虛方法。若在一個執行個體方法的聲明中含有virtual修飾符,則稱該方法為虛方法,否則稱為非虛方法。相對于非虛方法而言,虛方法可以由派生類來實作。在派生類中實作(使用override關鍵字)虛方法的過程被稱為重寫方法。簡而言之,虛方法可以被派生類重寫的,而非虛方法卻不能被重寫。

程式在Program類中聲明兩個方法:P1和P2。其中,P1為虛方法,P2為非虛方法。然後再建立一個Test類,它為Program類的派生類。Test類也聲明兩個方法:P1和P2。其中,P1使用override關鍵字重寫Program類中的P1方法,P2為非虛方法。

public class Program

{

   public Virtual void P1()        //虛方法

   {

      Console.WriteLine("Program.P1");

   }

   public void P2()                     //非虛方法

   {

      Console.WriteLine("Program.P2");

   }

}

public class Test : Program

{

      public override void P1()      //重寫了Porgram類的虛方法 P1

      {

         Console.WriteLine("Test .P1");

      }

      public void P2()                     //非虛方法 P2

      {

           Console.WriteLine("Test.P2")

      }

}

public class T

{

   static void Main()

   {

      Test t = new Test();

      Porgram p = new Porgram();

      Porgram program;

      program = p;

      program.P1();

      program = t;

      program.P1();

      program.P2();

     Console.WriteLine();

   }

}

代碼“program.P1();”中調用了子類的重寫的方法P1(),而子類中P2方法是非虛方法。是以“program.P2();”調用的是基類的方法P2()。

密封方法

C#繼承的功能很強大,但有時可能需要阻止某種繼承。例如,有一個封裝某些特定硬體裝置的初始化操作的類,我們不希望讓類的使用者能夠更改該裝置的初始化方式,因為使用者可能将裝置設定錯誤。是以,通過使用sealed關鍵字可以很容易地防止類被繼承。同樣地,在方法的聲明中添加關鍵字sealed,就可以防止任何該類的派生類重寫該方法。當執行個體方法聲明包含sealed修飾符時,稱該方法為密封方法(sealed method)。在聲明密封方法時,也必須同時添加override修飾符。

注意:使用sealed修飾符可以防止派生類進一步重寫該方法。即密封方法不能被派生類重寫。

建立一個Test2類,它為Program類的派生類。Test2類聲明一個方法:F1。該方法使用override關鍵字重寫Program類中的F1方法,并使用sealed修飾符把該方法設定為密封方法。

public class Test2:Program

{

public sealed override void P1()      //重寫了Program類的虛方法P1,并添加了sealed修飾符   

{       

 Console.WriteLine("Test2.P1");       //顯示“Test2.P1”字元串   

 }

}

抽象方法

有時我們想要建立一個方法,它隻定義其派生類共享的通用化形式,而讓派生類去實作具體内容。我們需要某種方式來確定派生類實際上重寫了方法。對于這個問題,C#的解決方法是使用抽象方法。當執行個體方法聲明包含abstract修飾符時,稱該方法為抽象方法(abstract method)。抽象方法不提供該方法的實作,它的方法體僅僅隻包含一個;(分号)。

注意:抽象方法隻能建立在抽象類中,且預設為虛方法。但是,在聲明抽象方法時,不能使用virtual修飾符。

建立一個抽象類Program,并在該類中聲明一個抽象方法Print()。該方法不包括其實際實作。

public abstract class Program

{   

public abstract void Print();              //Print()方法為抽象方法

}

屬性

屬性(property)是C#語言所特有的一種機制,它可以用于通路對象或類的特性的成員。屬性和字段非常相似,而且通路屬性和字段的文法相同。但是,屬性不表示存儲位置(字段表示一個存儲位置)。屬性通過一種被稱為通路器的機制來擷取或修改其值。其中,擷取屬性的值的通路器為稱為get通路器,修改屬性的值的通路器被稱為set通路器。

如果屬性隻包含get通路器,則稱該屬性為隻讀屬性。

如果屬性隻包含set通路器,則稱該屬性為隻寫屬性。

如果屬性既包含get通路器,又包含set通路器,則稱該屬性為讀寫屬性。

get通路器和set通路器的具體說明如下:

get通路器相當于一個無參數方法,且該通路的傳回值的類型和屬性的類型相同。在get通路器中,必須包含return語句,傳回該屬性的值。

set通路器相當于一個傳回類型為void的方法,且該方法隻有一個參數,參數的類型和屬性的類型相同。特别地,該方法的參數名稱始終約定為value。

聲明一個類型為string、名稱為Name的屬性。該屬性包含get和set通路器。get通路器用來擷取name私有變量的值,set通路器用來設定name私有變量的值。

public class Porgram

{

   private string name;     //聲明name字段

   public string Name

   {

      get { return name ;}

      set { name = value ;}

   }

   static void Main()

   {

      Porgram p = new Program();

      p.Name = "小明";

      string name =  p.Name;           //調用 get 通路器

      Console.WriteLine(name);

      Console.ReadLine();

   }

}

如果在聲明屬性時,使用了static修飾符,則稱該屬性為靜态屬性,否則稱該屬性為執行個體屬性。靜态屬性與執行個體屬性的差别和靜态字段與執行個體字段的差别相似。

注意:value為set通路器的隐式參數名稱,這是C#語言的一種約定。是以,value變量始終表示為set通路器的值,即使用者設定的值。且set通路器中不能包含“return 語句”的表達式。

索引器

在程式開發中,我們有時會需要對類的字段批量地做某種操作,比如字段的指派、周遊等。索引器允許按照與索引數組相同的方式索引對象。這樣我們就可以使用循環語句,通過下标的改變通路所有的對象中的字段,簡化了代碼。而且使用索引器,并不妨礙我們使用點運算符來調用類的某個字段。聲明索引器時,需要使用this關鍵字。

在Program類中聲明一個索引器。該索引器可以擷取或設定list數組(元素類型為string)的元素的值。另外,Program類在其構造函數(count為參數,它決定list數組的大小)中初始化list數組并指派。然後建立Program類的一個執行個體p,并把p執行個體的list數組的初始化為長度等于count變量的值100的數組。然後調用p執行個體的索引器輸出p執行個體的list數組的每一個元素。

public class Program

{

   private string[] list;

   public string this[index]        // 聲明索引器

   {

       get { return list[index]; }     // 擷取list數組中的元素

       set                                           //設定list元素的值

        {

            if(index >=1 && index<list.Length)

              {

                index = value;

              }

        }

    }

   public Program (int const)        // 構造函數

   {

       list = new string[const];

      for( int i=0; i<const ; i++)

      {

          list[i] = i.ToString;

      } 

   }

   static void Main()

   {

      int const = 100;

      Program p = new Program(const);

      for(int i=0;i<cont ;i++)

      {

           Console.Write(p[[i] + " ");

           if( i%10 == 0)

            {

                 Console.WriteLine();

            }

           Console.ReadLine();

       }

   }

}

雖然索引器也是一種屬性,但是它和屬性存在以下5點差別。

屬性存在一個名稱,而索引器由this關鍵字指定,即它所在類的簽名辨別。

屬性可以是靜态屬性(即使用static修飾),而索引器始終是執行個體成員(即不能使用static修飾)。

屬性可以通過成員來通路,而索引器必須通過其索引來通路其元素。

屬性的get通路器是不帶參數的方法,而索引器的get通路器為帶有參數(索引器的索引)的方法。

屬性的set通路器是僅僅帶有一個value參數的方法,而索引器的set通路器是除了value參數之外還帶有與索引相關的參數的方法。

注意:雖然索引器和數組比較相似,但是索引器不屬于變量,是以,索引器的元素不能作為ref或out參數傳遞。

構造函數

構造函數是類的一種特定的方法,通常用來初始化新對象的資料成員,即設定資料成員的預設值。構造函數是在建立給定類型的對象時執行的類方法,它的名稱和其所屬類的名稱相同。在任何時候,隻要建立類,就會調用它的構造函數。如果開發人員沒有為類顯式提供構造函數,則預設情況下C#編譯器将為該類建立一個預設的構造函數

在A類中聲明兩個構造函數:public A()和public A(int count)。

第一個構造函數不攜帶任何參數,它也不執行任何操作。

第二個構造函數攜帶類型int的count參數,它用來初始化list數組,并設定該數組每一個元素的值。

 public class A

 {

     private string[] list;        //元素類型為string的數組

     public A()                                         //構造函數

     {

     }

     public A(int count)                              //構造函數

     {

         list = new string[count];         //為list數組配置設定記憶體

         for(int i = 0; i < count; i++)      //為list數組的每一個元素指派

         {

             list[i] = i.ToString();

         }

     }

 }

“A a1 = new A()”語句将調用A類的A()構造函數,并建立A類的執行個體a1。

“A a2 = new A(2000)”語句将調用A類的A(int count)構造函數,并建立A類的執行個體a2。

構造函數可以分為執行個體構造函數和靜态構造函數。執行個體構造函數是不使用static修飾符的構造函數,而靜态構造函數是使用static修飾符的構造函數。

執行個體構造函數

在程式中,類的字段需要賦初值。使用構造函數有兩個重要的作用:

一是防止字段出現系統不合理的初始化;

二是更友善對字段進行初始化,簡化代碼。

執行個體構造函數是通過對象調用的,用于建立和初始化執行個體。執行個體構造函數在建立新對象時被調用,

public A()和public A(int count)構造函數都是屬于執行個體構造函數。

如果一個類不包含任何執行個體構造函數,那麼系統會自動地為該類提供一個預設執行個體構造函數。

預設構造函數調用該類的直接基類的無參數構造函數。

如果其基類沒有可通路的無參數執行個體構造函數,則發生編譯時錯誤。

如果執行個體構造函數使用private修飾符,那麼該構造函數為私有構造函數。私有構造函數是一種特殊的執行個體構造函數。它通常用在隻包含在靜态成員的類中。如果欲設計一個類并且不希望該類被執行個體化,則隻需在該類中聲明一個空的私有執行個體構造函數即可。

注意:預設構造函數将類的資料成員初始化為其類型的預設值(如果存在資料成員)。

程式中聲明一個名稱為Program的類,該類不包括任何構造函數。并且該類還包括兩個公開字段:name和age。

還聲明了一個類Jack,該類包含兩個公開靜态字段:name和age,它們的值分别為Jack和20。

 public class Program

 {

     public string name;                //聲明name字段

     public int age;                    //聲明age字段

 }

 public class Jack

 {

     public static string name = "Jack";          //靜态字段name

     public static int age = 20;                    //靜态字段age

     private Jack()                                       //私有構造函數

     {    }

 }

Program類沒有聲明構造函數,那麼系統會自動為該類添加一個預設構造函數,并設定name和age資料成員的值分别為null(string類型的預設值)和0(int類型的預設值)。Jack類包括了一個空的私有執行個體構造函數,該類不能被執行個體化。“Jack jack = new Jack()”表達式用來建立Jack類的執行個體會發生錯誤。

靜态構造函數

類有一些靜态字段或屬性,需要在第一次使用類之前,從外部源中初始化這些靜态字段和屬性。是以,靜态構造函數用于初始化類的靜态成員。

在建立第一個執行個體或引用任何靜态成員之前,将自動調用靜态構造函數。它也可以用于執行僅需執行一次的特定操作。

注意:靜态構造函數是不可繼承的,而且不能被直接調用。類的靜态構造函數在給定應用程式域中至多執行一次,它在第一次建立類的執行個體時或第一次引用類的任何靜态成員時被調用。

聲明名稱為Program的類,并且該類還包括兩個公開字段:name和age。其中,name字段為靜态字段。該類包括一個靜态構造函數Program(),并在該靜态構造函數中輸出“初始化Program”字元串。

另外,該類還包括一個靜态方法Show(),并在該方法中輸出“Program.Show()”字元串。然後調用Program類的靜态方法Show()(第一次被調用),并在調用該方法的同時也調用Program類的靜态構造函數Program ()。

public class Program

{

   public static string name;  //靜态字段

   public int age;

   static Porgram()     

   {

      Console.WriteLine("初始化 Porgram ");

   }

   public static void Show()

   {

      Console.WriteLine("Porgram.Show");

   }

   static void Main()

   {

      Program.Show();

      Console.ReadLine();

   }

}

程式代碼在調用Program類的靜态方法Show()(第一次被調用)的同時也調用Program類的靜态構造函數Program ()。

注意:Program類的靜态構造函數Program ()是通過Program.Show()方法觸發的。如果不是第一次調用Program類的Show()方法,則不會觸發Program類的靜态構造函數Program()。

靜态構造函數具有以下5個特點。

靜态構造函數一般用于初始化靜态字段、隻讀字段的值。

靜态構造函數既沒有通路修飾符(它預設為私有的),也沒有參數。聲明靜态構造函數時,需要添加static修飾符。

無法直接調用靜态構造函數,也無法控制何時執行靜态構造函數。

在建立第一個執行個體或引用任何靜态成員之前,将自動調用靜态構造函數來初始化類。

如果類中包含Main()方法,那麼該類的靜态構造函數将在調用Main()方法之前執行。如果類包含任何帶有初始值設定項的靜态字段,則在執行該類的靜态構造函數時,先要按照文本順序執行那些初始值設定項。

析構函數

計算機中的資源,使用完畢就應該釋放掉,給别的程式使用。而析構函數就是手動釋放類的執行個體占用的資源,并銷毀該類的執行個體。類的構造函數用來初始化該類的執行個體,析構函數和類的構造函數恰恰相反。析構函數的名稱和類的名稱一樣,并帶有“~”字元。通常情況下不需要使用析構函數。

聲明一個名稱為Program的類,該類包含了一個析構函數,并在該析構函數中輸出“銷毀Program類的執行個體”字元串。

public class Program

{   

               ~Program()            //析構函數   

        {       

                 Console.WriteLine("銷毀Program類的執行個體");   

        }

}

析構函數具有以下4個特點。

析構函數既沒有修飾符,也沒有參數。

無法調用析構函數。它們是被自動調用的。

隻能對類使用析構函數,而且一個類隻能有一個析構函數。

無法繼承或重載析構函數。

事件

事件在某些操作發生時自動地發出通知。比如說新員工到崗,需要給他辦理入職手續。入職手續有好幾個内容,這時我們可以定義一個事件,将這些内容封裝在一起。隻要有新員工到崗,就執行一次事件。事件是一種使對象或類能夠提供通知的成員。用戶端可以通過提供事件處理程式為相應的事件添加可執行代碼。類或對象可以通過事件向其他類或對象通知發生的相關事情。

一個類或對象可以事先向其他類或對象注冊一個事件,然後在一定的時候引發該事件。如開發人員可以向在Windows窗體中的按鈕注冊一個事件,當使用者單擊該按鈕時,将引發該已注冊的事件。

------- Windows Phone 7手機開發、.Net教育訓練、期待與您交流! -------