類型是由欄位資料(成員變數)和操作欄位資料的成員(屬性、方法、建構函式、事件等)所構成的自訂類型。其中欄位資料表示類執行個體(對象)的狀態。
在c#中,類使用class關鍵字定義,例如:
public class car
{
//car的欄位(狀態)
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;}
}
//顯式定義預設建構函式
public car(){}
//自訂建構函式
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);}
}
另:類的欄位很少被定義為公開的,為了保護狀態資料的完整性,最好把欄位資料定義為私人(或者受保護的),然後通過屬性對外提供受控制的訪問。
使用
new
關鍵字來指派至
對象必須使用了new關鍵字來分配到記憶體,如果不是用new,而隨後嘗試使用類變數的話,會收到一個編譯錯誤。
public static void main(string[] args)
{
//錯誤,忘記使用new
car c;
c.name="bruce";
}
正確的例子:
public static void main(string[] args)
{
//建立car對象。
car c;//聲明了指向尚未建立的car對象的引用。
c=new car("bruce wong",150);//通過new把有效引用賦給對象,這引用才會指向記憶體有效對象。
c.showstate();
console.readkey(true);
}
類建構函式
作用:給對象的欄位(狀態)賦值,它允許在建立對象時建立其狀態。
建構函式是類特殊的方法,在使用new關鍵字建立對象時被間接調用。
注意:建構函式沒有傳回值(即使是void),它的名字總是和類的名字一樣。
預設建構函式
c#提供一個預設的建構函式,需要時你可以重新定義,預設建構函式不接受任何參數。它把新的對象分配到記憶體和確保所有的欄位都被設定為正確的預設值。當你對這些預設值不滿意,你可以重新定義預設建構函式。如:
public car()
{
this._name="my car";
this._speed=100;
}
那麼每次使用new car()都會建立狀態_name="my car" _speed=100的car對象。
自訂建構函式
作用:在建立對象時可以直接初始化對象的狀態。
public car(string name,int speed)
{
this._name=name;
this._speed=speed;
}
注意:一旦定義了自訂函數,內建的預設建構函式就自動從類移除(不能用預設建構函式建立對象了)。如果希望使用預設建構函式建立類對象,就必須顯式定義預設建構函式。
this
關鍵字的作用
一、提供對當前執行個體的訪問。
可以解決傳入參數的名字與類型欄位名字相同時產生的範圍歧義。例如:
class car
{
private string name;
public void setname(string name)
{ this.name=name;}
}
表示把參數name的值賦給本對象(執行個體)的欄位name,this表示本執行個體。
二、參數傳遞。使用this進行串聯建構函式調用
使用一項名為建構函式鏈的技術來設計類。當類定義個了多個建構函式時,這個設計模式就會很有用。
由於建構函式通常會檢驗傳入的參數來強制各種商務規則,所以在類的建構函式集合中經常會找到冗餘的驗證邏輯。
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;
}
}
串聯建構函式方案:讓一個接受最多參數個數的建構函式做“主建構函式”,並實現必須的驗證邏輯。其餘的建構函式使用this關鍵字把參數轉給主建構函式,並提供其他必要參數。這樣,我們只關心主建構函式的邏輯,而其他建構函式體基本是空的了。
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){}
// 主建構函式
public car(int speed,string name)
{
if(speed>150) {speed=150;}
this.speed=speed;
this.name=name;
}
}
使用this關鍵字串聯建構函式方式可以簡化編程任務,類定義更加容易維護、更更加簡明。但它不是強制使用的。
串聯建構函式的執行順序:
1、調用建構函式把調用者提供的參數值轉寄給主建構函式,並提供其他必須的初始化參數值。
2、執行主建構函式。
3、執行調用建構函式體的邏輯。
三、自訂索引器
class carcollection:ienumerable
{
private arraylist arcar=new arraylist();
public car this[int index]
{
get{ return (car)arcar[index];}
set{arcar.insert(index,value);}
}
//...
}
static關鍵字
c#類(或者結構)可以使用static關鍵字來定義許多靜態成員。這些靜態成員只能從類層級而不能從對象層級上調用(調用靜態成員時不需要建立執行個體對象)。
例如:
//錯誤,writeline是靜態成員,是類層級的方法。
console c=new console();
c.writeline("bruce wong");
//正確!writeline是類層級的方法
console.writeline("bruce wong");
注意:
一、靜態成員只能操作待用資料或調用類的靜態成員。而非靜態成員可以操作執行個體資料與待用資料(成員),因為靜態成員對類的所有執行個體都是可用的。
二、clr把待用資料分配到記憶體只進行一次,改變待用資料將影響此類的所有執行個體。
定義靜態建構函式
建構函式用於在建立類對象時設定類對象的資料值。如果使用執行個體層級的建構函式給待用資料賦值,你會驚奇的發現每次建立類對象時待用資料的只都會被重設。所以我們要初始化待用資料最好使用靜態建構函式。
靜態建構函式是特殊的建構函式,它非常適用於初始化在編譯時間未知的待用資料的值:
一、一個類(結構)只能定義一個靜態建構函式。
二、靜態建構函式不允許存取修飾詞並且不能接受任何參數。
三、無論建立多少個類執行個體,靜態函數知執行一次。
四、clr建立類執行個體或首次調用類靜態成員前,clr會調用靜態建構函式。
五、靜態建構函式先於執行個體層級的其他建構函式執行。
靜態類:一個類被定義為靜態(使用static關鍵字修飾),就不能使用new關鍵字來建立類執行個體,靜態類只能包含用static標記的靜態類成員或欄位。
ps教程:項目的應用程式物件(如定義main()方法的類)通常定義為靜態類,以此來確保只包含靜態成員且不能被直接建立。如:
static class program
{
static void main(string[] args)
{
//...
}
}