C#中不同類的類型

字號:


    類類型是由字段數(shù)據(jù)(成員變量)和操作字段數(shù)據(jù)的成員(屬性、方法、構(gòu)造函數(shù)、事件等)所構(gòu)成的自定義類型。其中字段數(shù)據(jù)表示類實(shí)例(對象)的狀態(tài)。
    在C#中,類使用class關(guān)鍵字定義,例如:
    public class Car{
    //Car的字段(狀態(tài))
    private int _speed;
    private string _name;
    //Car操作字段的屬性
    public int Speed
    {
    set {this._speed=value;}
    get{return this._speed;}
    }
    public string Name
    {
    set { this._name=value;}
    get{return this._name;}
    }
    //顯式定義默認(rèn)構(gòu)造函數(shù)
    public Car(){}
    //自定義構(gòu)造函數(shù)
    public Car(string name,int speed)
    {
    this._name=name;
    this._speed=speed;
    }
    //Car的功能(方法)
    public void ShowState()
    {Console.WriteLine("Car {0} is going {1} MPH", this._name,this. _speed);}}
    另:類的字段很少被定義為公開的,為了保護(hù)狀態(tài)數(shù)據(jù)的完整性,最好把字段數(shù)據(jù)定義為私有(或者受保護(hù)的),然后通過屬性對外提供受控制的訪問。
    使用new關(guān)鍵字來分配對象
    對象必須使用了new關(guān)鍵字來分配到內(nèi)存,如果不是用new,而隨后嘗試使用類變量的話,會收到一個編譯錯誤。
    public static void Main(string[] args){
    //錯誤,忘記使用new
    Car c;
    c.Name="Bruce";}
    正確的例子:
    public static void Main(string[] args)
    {
    //創(chuàng)建Car對象。
    Car c;//聲明了指向尚未創(chuàng)建的Car對象的引用。
    c=new Car("bruce wong",150);//通過new把有效的引用賦給對象,這引用才會指向內(nèi)存有效的對象。
    c.ShowState();
    Console.ReadKey(true); }?
    類構(gòu)造函數(shù)
    作用:給對象的字段(狀態(tài))賦值,它允許在創(chuàng)建對象時創(chuàng)建其狀態(tài)。
    構(gòu)造函數(shù)是類特殊的方法,在使用new關(guān)鍵字創(chuàng)建對象時被間接調(diào)用。
    注意:構(gòu)造函數(shù)沒有返回值(即使是void),它的名字總是和類的名字一樣。
    默認(rèn)構(gòu)造函數(shù)
    C#提供一個默認(rèn)的構(gòu)造函數(shù),需要時你可以重新定義,默認(rèn)構(gòu)造函數(shù)不接受任何參數(shù)。它把新的對象分配到內(nèi)存和確保所有的字段都被設(shè)置為正確的默認(rèn)值。當(dāng)你對這些默認(rèn)值不滿意,你可以重新定義默認(rèn)構(gòu)造函數(shù)。如:
    public Car(){
    this._name="My Car";
    this._speed=100;}
    那么每次使用new Car()都會創(chuàng)建狀態(tài)_name="My Car" _speed=100的Car對象。
    自定義構(gòu)造函數(shù)
    作用:在創(chuàng)建對象時可以直接初始化對象的狀態(tài)。
    public Car(string name,int speed)
    {
    this._name=name;
    this._speed=speed;
    }
    注意:一旦定義了自定義函數(shù),自帶的默認(rèn)構(gòu)造函數(shù)就自動從類移除(不能用默認(rèn)構(gòu)造函數(shù)創(chuàng)建對象了)。如果希望使用默認(rèn)構(gòu)造函數(shù)創(chuàng)建類對象,就必須顯式定義默認(rèn)構(gòu)造函數(shù)。
    this關(guān)鍵字的作用
    一、提供對當(dāng)前實(shí)例的訪問。
    可以解決傳入?yún)?shù)的名字與類型字段名字相同時產(chǎn)生的作用域歧義。例如:
    class Car{
    private string name;
    public void SetName(string name)
    { this.name=name;}}
    表示把參數(shù)name的值賦給本對象(實(shí)例)的字段name,this表示本實(shí)例。
    二、參數(shù)傳遞。使用this進(jìn)行串聯(lián)構(gòu)造函數(shù)調(diào)用
    使用一項(xiàng)名為構(gòu)造函數(shù)鏈的技術(shù)來設(shè)計類。當(dāng)類定義個了多個構(gòu)造函數(shù)時,這個設(shè)計模式就會很有用。
    由于構(gòu)造函數(shù)通常會檢驗(yàn)傳入的參數(shù)來強(qiáng)制各種業(yè)務(wù)規(guī)則,所以在類的構(gòu)造函數(shù)集合中經(jīng)常會找到冗余的驗(yàn)證邏輯。
    class Car{
    public int Speed{get;set;}
    public string Name{get;set;}
    public Car(){}
    public Car(int speed){if(speed>150){speed=150;}this.Speed=speed;}
    public Car(string name){this.Name=name;}
    public Car(int speed,string name){if(speed>150){speed=150;}this.Speed=speed;this.Name=name;}}
    串聯(lián)構(gòu)造函數(shù)方案:讓一個接受最多參數(shù)個數(shù)的構(gòu)造函數(shù)做“主構(gòu)造函數(shù)”,并實(shí)現(xiàn)必須的驗(yàn)證邏輯。其余的構(gòu)造函數(shù)使用this關(guān)鍵字把參數(shù)轉(zhuǎn)給主構(gòu)造函數(shù),并提供其他必需的參數(shù)。這樣,我們只關(guān)心主構(gòu)造函數(shù)的邏輯,而其他構(gòu)造函數(shù)體基本是空的了。
    class Car{
    public int Speed{get;set;}
    public string Name{get;set;}
    public Car(){}
    public Car(int speed):this(speed,""){}
    public Car(string name):this(0,name){}
    // 主構(gòu)造函數(shù) public Car(int speed,string name)
    {
    if(speed>150) {speed=150;}
    this.Speed=speed;
    this.Name=name;
    }}
    使用this關(guān)鍵字串聯(lián)構(gòu)造函數(shù)方式可以簡化編程任務(wù),類定義更加容易維護(hù)、更更加簡明。但它不是強(qiáng)制使用的。
    串聯(lián)構(gòu)造函數(shù)的執(zhí)行順序:
    1、調(diào)用構(gòu)造函數(shù)把調(diào)用者提供的參數(shù)值轉(zhuǎn)發(fā)給主構(gòu)造函數(shù),并提供其他必須的初始化參數(shù)值。
    2、執(zhí)行主構(gòu)造函數(shù)。
    3、執(zhí)行調(diào)用構(gòu)造函數(shù)體的邏輯。
    三、自定義索引器
    class CarCollection:IEnumerable{
    private ArrayList arCar=new ArrayList();
    public Car this[int index]
    {
    get{ return (Car)arCar[index];}
    set{arCar.Insert(index,value);}
    }
    //...}
    static關(guān)鍵字
    C#類(或者結(jié)構(gòu))可以使用static關(guān)鍵字來定義許多靜態(tài)成員。這些靜態(tài)成員只能從類級別而不能從對象級別上調(diào)用(調(diào)用靜態(tài)成員時不需要創(chuàng)建實(shí)例對象)。
    例如:
    //錯誤,WriteLine是靜態(tài)成員,是類級別的方法。Console c=new Console();c.WriteLine("Bruce Wong");//正確!WriteLine是類級別的方法Console.WriteLine("Bruce Wong");
    注意:
    一、靜態(tài)成員只能操作靜態(tài)數(shù)據(jù)或調(diào)用類的靜態(tài)成員。而非靜態(tài)成員可以操作實(shí)例數(shù)據(jù)與靜態(tài)數(shù)據(jù)(成員),因?yàn)殪o態(tài)成員對類的所有實(shí)例都是可用的。
    二、CLR把靜態(tài)數(shù)據(jù)分配到內(nèi)存只進(jìn)行一次,改變靜態(tài)數(shù)據(jù)將影響此類的所有實(shí)例。
    定義靜態(tài)構(gòu)造函數(shù)
    構(gòu)造函數(shù)用于在創(chuàng)建類對象時設(shè)置類對象的數(shù)據(jù)值。如果使用實(shí)例級別的構(gòu)造函數(shù)給靜態(tài)數(shù)據(jù)賦值,你會驚奇的發(fā)現(xiàn)每次新建類對象時靜態(tài)數(shù)據(jù)的只都會被重置。所以我們要初始化靜態(tài)數(shù)據(jù)最好使用靜態(tài)構(gòu)造函數(shù)。
    靜態(tài)構(gòu)造函數(shù)是特殊的構(gòu)造函數(shù),它非常適用于初始化在編譯時未知的靜態(tài)數(shù)據(jù)的值:
    一、一個類(結(jié)構(gòu))只能定義一個靜態(tài)構(gòu)造函數(shù)。
    二、靜態(tài)構(gòu)造函數(shù)不允許訪問修飾符并且不能接受任何參數(shù)。
    三、無論創(chuàng)建多少個類實(shí)例,靜態(tài)函數(shù)知執(zhí)行一次。
    四、CLR創(chuàng)建類實(shí)例或首次調(diào)用類靜態(tài)成員前,CLR會調(diào)用靜態(tài)構(gòu)造函數(shù)。
    五、靜態(tài)構(gòu)造函數(shù)先于實(shí)例級別的其他構(gòu)造函數(shù)執(zhí)行。
    靜態(tài)類:一個類被定義為靜態(tài)的(使用static關(guān)鍵字修飾),就不能使用new關(guān)鍵字來創(chuàng)建類實(shí)例,靜態(tài)類只能包含用static標(biāo)記的靜態(tài)類成員或字段。
    PS:項(xiàng)目的應(yīng)用程序?qū)ο?如定義Main()方法的類)通常定義為靜態(tài)類,以此來確保只包含靜態(tài)成員且不能被直接創(chuàng)建。如:
    static class Program{
    static void Main(string[] args)
    {
    //...
    }}