C 繼承機制 訪問與隱藏基類成員

2022-08-28 03:30:13 字數 3530 閱讀 5265

(1) 訪問基類成員

通過base 關鍵字訪問基類的成員: 

呼叫基類上已被其他方法重寫的方法。 

指定建立派生類例項時應呼叫的基類建構函式。 

基類訪問只能在建構函式、例項方法或例項屬性訪問器中進行。

從靜態方法中使用 base 關鍵字是錯誤的。

示例:下面程式中基類 person 和派生類 employee 都有乙個名為 getinfo 的方法。通過使用 base 關鍵字,可以從派生類中呼叫基類上的 getinfo 方法。

using system ;

public class person 

", name) ;

console.writeline("編號: ", ssn) ;}}

class employee: person 

", id) ;}}

class testclass

} 程式執行輸出:

姓名: 張三

編號: 111-222-333-444

成員id: abc567efg23267

示例:派生類同基類進行通訊。

using system ;

public class parent

public parent(string mystring)

public void print( )

}public class child : parent

public void print( )

public static void main( )

} 程式執行輸出: 

from derived

child constructor.

i'm a parent class.

i'm a child class.

i'm a parent class.

說明:1.派生類在初始化的過程中可以同基類進行通訊。

上面**演示了在子類的建構函式定義中是如何實現同基類通訊的。分號":"和關鍵字base用來呼叫帶有相應引數的基類的建構函式。輸出結果中,第一行表明:基類的建構函式最先被呼叫,其實在引數是字串"from derived"。

2.有時,對於基類已有定義的方法,打算重新定義自己的實現。

child類可以自己重新定義print( )方法的實現。child的print( )方法覆蓋了parent中的 print 方法。結果是:除非經過特別指明,parent類中的print方法不會被呼叫。

3.在child類的 print( ) 方法中,我們特別指明:呼叫的是parent類中的 print( ) 方法。

方法名前面為"base",一旦使用"base"關鍵字之後,你就可以訪問基類的具有公有或者保護許可權的成員。 child類中的print( )方法的執行結果出現上面的第三行和第四行。

4.訪問基類成員的另外一種方法是:通過顯式型別轉換。

在child類的main( )方法中的最後一條語句就是這麼做的。記住:派生類是其基類的特例。這個事實告訴我們:可以在派生類中進行資料型別的轉換,使其成為基類的乙個例項。上面**的最後一行實際上執行了parent類中的 print( )方法。

(2) 隱藏基類成員

想想看,如果所有的類都可以被繼承,繼承的濫用會帶來什麼後果?類的層次結構體系將變得十分龐,大類之間的關係雜亂無章,對類的理解和使用都會變得十分困難。有時候,我們並不希望自己編寫的類被繼承。另一些時候,有的類已經沒有再被繼承的必要。c#提出了乙個密封類(sealed class)的概念,幫助開發人員來解決這一問題。

密封類在宣告中使用sealed 修飾符,這樣就可以防止該類被其它類繼承。如果試圖將乙個密封類作為其它類的基類,c#將提示出錯。理所當然,密封類不能同時又是抽象類,因為抽象總是希望被繼承的。

在哪些場合下使用密封類呢?密封類可以阻止其它程式設計師在無意中繼承該類。而且密封類可以起到執行時優化的效果。實際上,密封類中不可能有派生類。如果密封類例項中存在虛成員函式,該成員函式可以轉化為非虛的,函式修飾符virtual 不再生效。

讓我們看下面的例子:

bstract class a

sealed class b: a

}如果我們嘗試寫下面的**

class c: b

c#會指出這個錯誤,告訴你b 是乙個密封類,不能試圖從b 中派生任何類。

(3) 密封方法

我們已經知道,使用密封類可以防止對類的繼承。c#還提出了密封方法(sealedmethod) 的概念,以防止在方法所在類的派生類中對該方法的過載。對方法可以使用sealed 修飾符,這時我們稱該方法是乙個密封方法。

不是類的每個成員方法都可以作為密封方法密封方法,必須對基類的虛方法進行過載,提供具體的實現方法。所以,在方法的宣告中,sealed 修飾符總是和override 修飾符同時使用。請看下面的例子**:

using system ;

class a

public virtual void g( ) 

}class b: a

override public void g( ) 

}class c: b

} 類b 對基類a 中的兩個虛方法均進行了過載,其中f 方法使用了sealed 修飾符,成為乙個密封方法。g 方法不是密封方法,所以在b 的派生類c 中,可以過載方法g,但不能過載方法f。

(4) 使用 new 修飾符隱藏基類成員

使用 new 修飾符可以顯式隱藏從基類繼承的成員。若要隱藏繼承的成員,請使用相同名稱在派生類中宣告該成員,並用 new 修飾符修飾它。

請看下面的類:

public class mybase 

在派生類中用 myvoke名稱宣告成員會隱藏基類中的 myvoke方法,即:

public class myderived : mybase

但是,因為字段 x 不是通過類似名隱藏的,所以不會影響該欄位。

通過繼承隱藏名稱採用下列形式之一:

a、引入類或結構中的常數、指定、屬性或型別隱藏具有相同名稱的所有基類成員。

b、引入類或結構中的方法隱藏基類中具有相同名稱的屬性、欄位和型別。同時也隱藏具有相同簽名的所有基類方法。

c、引入類或結構中的索引器將隱藏具有相同名稱的所有基類索引器。

注意:在同一成員上同時使用 new 和 override 是錯誤的。同時使用 new 和 virtual 可保證乙個新的專用化點。在不隱藏繼承成員的宣告中使用 new 修飾符將發出警告。

示例1:在該例中,基類 mybasec 和派生類 myderivedc 使用相同的欄位名 x,從而隱藏了繼承欄位的值。該例說明了 new 修飾符的使用。同時也說明了如何使用完全限定名訪問基類的隱藏成員。

using system ;

public class mybase 

public class myderived : mybase

}輸出: 100 55 22

如果移除 new 修飾符,程式將繼續編譯和執行,但您會收到以下警告:

the keyword new is required on 'myderivedc.x' because it hides inherited member 'mybasec.x'.

如果巢狀型別正在隱藏另一種型別,如下例所示,也可以使用 new 修飾符修改此巢狀型別。

C 中基類成員函式的隱藏機制

在c 類的繼承中,宣告在內層作用域 派生類 的函式並不會過載宣告在外層作用域 基類 的函式。因此,定義在派生類中的函式也不會過載基類中的成員。如果派生類和基類中的某個成員重名,則派生類將在其作用域內隱藏該基類成員。即使派生類成員列表和基類成員列表不一致,基類成員也依然被隱藏。struct base ...

繼承類對基類成員的訪問許可權

繼承是事物發展的過程,通過繼承使得後代繼承了父輩的優秀屬性並進一步 拓展出新的屬性和能力。c 中的繼承就是現有的類中建立乙個新的類,現有的類成為基類,繼承出來的新類稱為派生類,可以簡單的理解為 基類為父親,派生類為兒子。繼承的方式有三種,分別是 公有繼承 public 私有繼承 private 保護...

public繼承後,父類與子類訪問隱藏

子類父類同名virtual函式 引數相同 用子類的指標,引用,物件訪問時,子類會覆蓋父類方法 只能訪問子類方法 子類父類同名virtual函式 引數相同 用父類的指標,引用,物件訪問時,子類會覆蓋父類方法 只能訪問子類方法 子類父類同名virtual函式 引數不同 用子類的指標,引用,物件訪問時,子...