三種繼承的方法:public 繼承/private繼承/protected繼承詳解及區別

bzhxuexi發表於2013-11-29

公有繼承(public)、私有繼承(private)、保護繼承(protected)是常用的三種繼承方式。  
1. 公有繼承(public)   
公有繼承的特點是基類的公有成員和保護成員作為派生類的成員時,它們都保持原有的狀態,而基類的私有成員仍然是私有的,不能被這個派生類的子類所訪問。  
2. 私有繼承(private)  ------------------預設的繼承方式(如果預設,預設為private繼承)

私有繼承的特點是基類的公有成員和保護成員都作為派生類的私有成員,並且不能被這個派生類的子類所訪問。 

 子類也不能轉換成相應的基類,如果轉換,會報錯:“不允許對不可訪問的基類進行轉換”。
3. 保護繼承(protected)   
保護繼承的特點是基類的所有公有成員和保護成員都成為派生類的保護成員,並且只能被它的派生類成員函式或友元訪問,基類的私有成員仍然是私有的。  
下面列出三種不同的繼承方式的基類特性和派生類特性。  

  public protected private
公有繼承 public protected 不可見
私有繼承 private private 不可見
保護繼承 protected protected 不可見

 為了進一步理解三種不同的繼承方式在其成員的可見性方面的區別,下面從三種不同角度進行討論。

對於公有繼承方式

(1) 基類成員對其物件的可見性:  
公有成員可見,其他不可見。這裡保護成員同於私有成員。
   
(2) 基類成員對派生類的可見性:  
公有成員和保護成員可見,而私有成員不可見。這裡保護成員同於公有成員。
   
(3) 基類成員對派生類物件的可見性:  
公有成員可見,其他成員不可見。  

所以,在公有繼承時,派生類的物件可以訪問基類中的公有成員;派生類的成員函式可以訪問基類中的公有成員和保護成員。這裡,一定要區分清楚派生類的物件和派生類中的成員函式對基類的訪問是不同的。

對於私有繼承方式

(1) 基類成員對其物件的可見性:  
公有成員可見,其他成員不可見。  
(2) 基類成員對派生類的可見性:  
公有成員和保護成員是可見的,而私有成員是不可見的。  
(3) 基類成員對派生類物件的可見性:  
所有成員都是不可見的。  
所以,在私有繼承時,基類的成員只能由直接派生類訪問,而無法再往下繼承。

對於保護繼承方式

  這種繼承方式與私有繼承方式的情況相同。兩者的區別僅在於對派生類的成員而言,對基類成員有不同的可見性。  上述所說的可見性也就是可訪問性。關於可訪問性還有另的一種說法。這種規則中,稱派生類的物件對基類訪問為水平訪問,稱派生類的派生類對基類的訪問為垂直訪問。

一般規則

公有繼承時,水平訪問和垂直訪問對基類中的公有成員不受限制;  
私有繼承時,水平訪問和垂直訪問對基類中的公有成員也不能訪問;  
保護繼承時,對於垂直訪問同於公有繼承,對於水平訪問同於私有繼承。  
對於基類中的私有成員,只能被基類中的成員函式和友元函式所訪問,不能被其他的函式訪問。  

基類與派生類的關係:任何一個類都可以派生出一個新類,派生類也可以再派生出新類,因此,基類和派生類是相對而言的。

基類與派生類之間的關係

1. 派生類是基類的具體化

  類的層次通常反映了客觀世界中某種真實的模型。在這種情況下,不難看出:基類是對若干個派生類的抽象,而派生類是基類的具體化。基類抽取了它的派生類的公共特徵,而派生類通過增加行為將抽象類變為某種有用的型別。

2. 派生類是基類定義的延續

  先定義一個抽象基類,該基類中有些操作並未實現。然後定義非抽象的派生類,實現抽象基類中定義的操作。例如,虛擬函式就屬此類情況。這時,派生類是抽象的基類的實現,即可看成是基類定義的延續。這也是派生類的一種常用方法。

3. 派生類是基類的組合

  在多繼承時,一個派生類有多於一個的基類,這時派生類將是所有基類行為的組合。  派生類將其本身與基類區別開來的方法是新增資料成員和成員函式。因此,繼承的機制將使得在建立新類時,只需說明新類與已有類的區別,從而大量原有的程式程式碼都可以複用,所以有人稱類是“可複用的軟體構件”。

-------------------------------------------------------另-----------------------------------

(1)子類對父類成員的訪問許可權跟如何繼承沒有任何關係,“子類可以訪問父類的public和protected成員,不可以訪問父類的private成員”——這句話對任何一種繼承都是成立的。
(2)繼承修飾符影響著誰可以知道“繼承”這件事。public繼承大家都知道,有點像“法定繼承人”,因此,任何程式碼都可以把子類的引用(或指標)直接轉換為父類。也因為這個原因,public繼承常用來表達設計中所謂的“is-a”關係。private繼承則有點像“私生子”,除了子類自己,沒有人知道這層關係,也因此,除了子類自己的程式碼之外,沒有其它人知道自己還有個父親,於是也就沒有其它人可以做相應的型別轉換。為此,私有繼承常用於表達非“is-a”的關係,這種情況下子類只是借用父類的某些實現細節。protected繼承則有點特殊,外界同樣不知道這層關係,但家族內部的子孫們可以知道,有點像“自家知道就行了,不許外揚”的意思,於是子孫們是可以做這種向上轉型,其它程式碼則不可以。因為這種特殊性,protected繼承在實際中用得很少。
(3)還需要補充一點,由於“繼承關係”的可見性受到了影響,那麼繼承來的財產的可見性也必然受到影響。比如一個成員變數或成員函式,在父類中本來是public的,被某個子類protected繼承之後,對子類來講,這個成員就相當於protected成員了——繼承是繼承到了,但許可權變了。具體的規則教材上都會講的。

相關文章