和類的成員方法一樣,我們也可以定義屬性的重載、虛屬性、抽象屬性以及密封屬性的概念。
與類和方法一樣,屬性的修飾也應符合下列規則:
屬性的重載
●在派生類中使用修飾符的屬性,表示對基類中的同名屬性進行重載。
●在重載的聲明中,屬性的名稱、類型、訪問修飾符都應該與基類中被繼承的屬性一致。
●如果基類的屬性只有一個屬性訪問器,重載後的屬性也應只有一個。但如果基類的屬性同時包含get和set屬性訪問器,重載後的屬性可以只有一個,也可以同時有兩個屬性訪問器。
注意:與方法重載不同的是,屬性的重載聲明實際上並沒有聲明新的屬性,而只是為已有的虛屬性提供訪問器的具體實現。
虛屬性
●使用virtual修飾符聲明的屬性為虛屬性。
●虛屬性的訪問器,包括get訪問器和set訪問器,同樣也是虛的。
抽象屬性
●使用abstract修飾符聲明的屬性為抽象屬性
●抽象屬性的訪問器也是虛的,而且沒有提供訪問器的具體實現。這就要求在非虛的派生類中,由派生類自己通過重載屬性來提供對訪問器的具體實現。
●abstract和override修飾符的同時使用,不但表示屬性是抽象的,而且它重載了其類中的虛屬性。這是屬性的訪問器也是抽象的。
●抽象屬性只允許在抽象類中聲明。
●除了同時使用abstract和override修飾符這種情況之外,static,virtual,override和abstract修飾符中任意兩個不能再同時出現。
密封屬性
●使用sealed修飾符聲明的屬性為密封屬性。類的密封屬性不允許在派生類中被繼承。密封屬性的訪問器同樣也是密封的。
●屬性聲明時如果有sealed修飾符,同時也必須要有override修飾符。
從上面可以看出,屬性的這些規則與方法十分類似。對於屬性的訪問器,我們可以把get訪問器看成是一個與屬性修飾符相同、沒有參數、返回值為屬性的值類型的方法;把set訪問器看成是一個與屬性修飾符相同、僅含有一個value參數、返回類型為void的方法。還記得第十章中客戶住宿的例子嗎?還是讓我們擴展這個例子來說明屬性在繼承中的一些問題。
程序清單14-8:
using System; public enum sex { woman, man, }; abstract public class People { private string s_name; public virtual string Name{ get{ return s_name; } } private sex m_sex; public virtual sex Sex{ get{ return m_sex; } protected string s_card; public abstract string Card { get;set; } }
上面的例子中聲明了“人”這個類,人的姓名Name和性別Sex是兩個只讀的虛屬性;身份證號Card是一個抽象屬性,允許讀寫。因為類People中包含了抽象屬性Card,所以Pelple必須聲明是抽象的。下面我們為住宿的客人編寫一個類,類從People中繼承。
程序清單14-9:
class Customer:People { string s_no; int i_day; public string No{ get{ return s_no; } set{ if(s_no!=value){ s_no=value; } } } public int Day{ get{ return i_day; } set{ if(i_day!=value){ i_day=value; } } } public override string Name{ get{return base.Name;} } public override sex Sex{ get(return base.Sex} } public override string Card{ get{ return s_card; } set{ s_card=value; } } }
在類Customer中,屬性Name、Sex和Card的聲明都加上了override修飾符,屬性的聲明都與基類People中保持一致。Name和Sex的get訪問器、Card的get和set訪問器都使用了base關鍵字來訪問基類People中的訪問器。屬性Card的聲明重載了基類People中的抽象訪問器。這樣,在Customer類中沒有抽象成員的存在,Customer可以是非虛的。