深入剖析C#繼承機(jī)制6
2024-07-21 02:18:21
供稿:網(wǎng)友
五、繼承與訪問(wèn)修飾符
訪問(wèn)修飾符是一些關(guān)鍵字,用于指定聲明的成員或類型的可訪問(wèn)性。類的繼承中有四個(gè)訪問(wèn)修飾符: public protected internal private。使用這些訪問(wèn)修飾符可指定下列五個(gè)可訪問(wèn)性級(jí)別: public protected internal internal protected private。
聲明的可訪問(wèn)性 意義
public 訪問(wèn)不受限制。
protected 訪問(wèn)僅限于包含類或從包含類派生的類型。
internal 訪問(wèn)僅限于當(dāng)前項(xiàng)目。
protected internal 訪問(wèn)僅限于從包含類派生的當(dāng)前項(xiàng)目或類型。
private 訪問(wèn)僅限于包含類型。
1、繼承中關(guān)于可訪問(wèn)域的一些問(wèn)題
基類的所有成員(實(shí)例構(gòu)造函數(shù)、析構(gòu)函數(shù)和靜態(tài)構(gòu)造函數(shù)除外)都由派生類型繼承。這甚至包括基類的私有成員。但是,私有成員的可訪問(wèn)域只包括聲明該成員的類型的程序文本。在下面的示例中
class a
{
int x ;
static void f(b b) {
b.x = 1 ; // 對(duì)
}
}
class b: a
{
static void f(b b) {
b.x = 1 ; // 錯(cuò)誤
}
}
類 b 繼承類 a 的私有成員 x。因?yàn)樵摮蓡T是私有的,所以只能在 a 的"類體"中對(duì)它進(jìn)行訪問(wèn)。因此,對(duì) b.x 的訪問(wèn)在 a.f 方法中取得了成功,在 b.f 方法中卻失敗了。
2、繼承中關(guān)于屬性的一些問(wèn)題
和類的成員方法一樣,我們也可以定義屬性的重載、虛屬性、抽象屬性以及密封屬性的概念。與類和方法一樣,屬性的修飾也應(yīng)符合下列規(guī)則:
屬性的重載
1. 在派生類中使用修飾符的屬性,表示對(duì)基類中的同名屬性進(jìn)行重載。
2. 在重載的聲明中,屬性的名稱、類型、訪問(wèn)修飾符都應(yīng)該與基類中被繼承的屬性一致。
3. 如果基類的屬性只有一個(gè)屬性訪問(wèn)器,重載后的屬性也應(yīng)只有一個(gè)。但如果基類的屬性同時(shí)包含get 和set 屬性訪問(wèn)器,重載后的屬性可以只有一個(gè),也可以同時(shí)有兩個(gè)屬性訪問(wèn)器。
注意:與方法重載不同的是,屬性的重載聲明實(shí)際上并沒(méi)有聲明新的屬性,而只是為已有的虛屬性提供訪問(wèn)器的具體實(shí)現(xiàn)。
虛屬性
1. 使用virtual 修飾符聲明的屬性為虛屬性。
2. 虛屬性的訪問(wèn)器包括get 訪問(wèn)器和set 訪問(wèn)器,同樣也是虛的。
抽象屬性
1. 使用abstract 修飾符聲明的屬性為抽象屬性。
2. 抽象屬性的訪問(wèn)器也是虛的,而且沒(méi)有提供訪問(wèn)器的具體實(shí)現(xiàn)。這就要求在非虛的派生類中,由派生類自己通過(guò)重載屬性來(lái)提供對(duì)訪問(wèn)器的具體實(shí)現(xiàn)。
3. abstract 和override 修飾符的同時(shí)使用,不但表示屬性是抽象的,。而且它重載了基類中的虛屬性這時(shí)屬性的訪問(wèn)器也是抽象的。
4. 抽象屬性只允許在抽象類中聲明。
5. 除了同時(shí)使用abstract 和override 修飾符這種情況之外,static, virtual, override和abstract 修飾符中任意兩個(gè)不能再同時(shí)出現(xiàn)。
密封屬性
1. 使用sealed 修飾符聲明的屬性為密封屬性。類的密封屬性不允許在派生類中被繼承。密封屬性的訪問(wèn)器同樣也是密封的。
2. 屬性聲明時(shí)如果有sealed 修飾符,同時(shí)也必須要有override 修飾符。
從上面可以看出,屬性的這些規(guī)則與方法十分類似。對(duì)于屬性的訪問(wèn)器,我們可以把get 訪問(wèn)器看成是一個(gè)與屬性修飾符相同、沒(méi)有參數(shù)、返回值為屬性的值類型的方法,把set 訪問(wèn)器看成是一個(gè)與屬性修飾符相同、僅含有一個(gè)value 參數(shù)、返回類型為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; }
}
上面的例子中聲明了"人"這個(gè)類,人的姓名name 和性別sex 是兩個(gè)只讀的虛屬性:身份證號(hào)card 是一個(gè)抽象屬性,允許讀寫(xiě),因?yàn)轭恜eople 中包含了抽象屬性card,所以people 必須聲明是抽象的。下面我們?yōu)樽∷薜目腿司帉?xiě)一個(gè)類類從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 訪問(wèn)器,card 的get 和set訪問(wèn)器都使用了base 關(guān)鍵字來(lái)訪問(wèn)基類people 中的訪問(wèn)器屬性。card 的聲明重載了基類people 中的抽象訪問(wèn)器。這樣,在customer 類中沒(méi)有抽象成員的存在,customer可以是非虛的。