訪問修飾符是一些關鍵字,用於指定聲明的成員或類型的可訪問性。類的繼承中有四個訪問修飾符: public protected internal private。使用這些訪問修飾符可指定下列五個可訪問性級別: public protected internal internal protected private。
聲明的可訪問性 | 意義 |
public | 訪問不受限制。 |
protected | 訪問僅限於包含類或從包含類派生的類型。 |
internal | 訪問僅限於當前項目。 |
protected internal | 訪問僅限於從包含類派生的當前項目或類型。 |
private | 訪問僅限於包含類型。 |
1、繼承中關於可訪問域的一些問題
基類的所有成員(實例構造函數、析構函數和靜態構造函數除外)都由派生類型繼承。這甚至包括基類的私有成員。但是,私有成員的可訪問域只包括聲明該成員的類型的程序文本。在下面的示例中
class A { int x ; static void F(B b) { b.x = 1 ; // 對 } } class B: A { static void F(B b) { b.x = 1 ; // 錯誤 } } |
類 B 繼承類 A 的私有成員 x。因爲該成員是私有的,所以只能在 A 的"類體"中對它進行訪問。因此,對 b.x 的訪問在 A.F 方法中取得了成功,在 B.F 方法中卻失敗了。
2、繼承中關於屬性的一些問題
和類的成員方法一樣,我們也可以定義屬性的重載、虛屬性、抽象屬性以及密封屬性的概念。與類和方法一樣,屬性的修飾也應符合下列規則:
屬性的重載
1. 在派生類中使用修飾符的屬性,表示對基類中的同名屬性進行重載。
2. 在重載的聲明中,屬性的名稱、類型、訪問修飾符都應該與基類中被繼承的屬性一致。
3. 如果基類的屬性只有一個屬性訪問器,重載後的屬性也應只有一個。但如果基類的屬性同時包含get 和set 屬性訪問器,重載後的屬性可以只有一個,也可以同時有兩個屬性訪問器。
注意:與方法重載不同的是,屬性的重載聲明實際上並沒有聲明新的屬性,而只是爲已有的虛屬性提供訪問器的具體實現。
虛屬性
1. 使用virtual 修飾符聲明的屬性爲虛屬性。
2. 虛屬性的訪問器包括get 訪問器和set 訪問器,同樣也是虛的。
抽象屬性
1. 使用abstract 修飾符聲明的屬性爲抽象屬性。
2. 抽象屬性的訪問器也是虛的,而且沒有提供訪問器的具體實現。這就要求在非虛的派生類中,由派生類自己通過重載屬性來提供對訪問器的具體實現。
3. abstract 和override 修飾符的同時使用,不但表示屬性是抽象的,。而且它重載了基類中的虛屬性這時屬性的訪問器也是抽象的。
4. 抽象屬性只允許在抽象類中聲明。
5. 除了同時使用abstract 和override 修飾符這種情況之外,static, virtual, override和abstract 修飾符中任意兩個不能再同時出現。
密封屬性
1. 使用sealed 修飾符聲明的屬性爲密封屬性。類的密封屬性不允許在派生類中被繼承。密封屬性的訪問器同樣也是密封的。
2. 屬性聲明時如果有sealed 修飾符,同時也必須要有override 修飾符。
從上面可以看出,屬性的這些規則與方法十分類似。對於屬性的訪問器,我們可以把get 訪問器看成是一個與屬性修飾符相同、沒有參數、返回值爲屬性的值類型的方法,把set 訪問器看成是一個與屬性修飾符相同、僅含有一個value 參數、返回類型爲void 的方法。看下面的程序:
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,所以People 必須聲明是抽象的。下面我們爲住宿的客人編寫一個類類從People 中繼承。再看下面的程序:
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可以是非虛的。