C++三種繼承方式

C++繼承的一般語法為:
class 派生類名:[繼承方式] 基類名{
??? 派生類新增加的成員
};
繼承方式限定了基類成員在派生類中的訪問權(quán)限,包括 public(公有的)、private(私有的)和 protected(受保護(hù)的)。此項(xiàng)是可選項(xiàng),如果不寫,默認(rèn)為 private(成員變量和成員函數(shù)默認(rèn)也是 private)。
現(xiàn)在我們知道,public、protected、private 三個(gè)關(guān)鍵字除了可以修飾類的成員,還可以指定繼承方式。
public、protected、private 修飾類的成員
類成員的訪問權(quán)限由高到低依次為 public --> protected --> private,我們?cè)凇禖++類成員的訪問權(quán)限以及類的封裝》一節(jié)中講解了 public 和 private:public 成員可以通過對(duì)象來訪問,private 成員不能通過對(duì)象訪問。
現(xiàn)在再來補(bǔ)充一下 protected。protected 成員和 private 成員類似,也不能通過對(duì)象訪問。但是當(dāng)存在繼承關(guān)系時(shí),protected 和 private 就不一樣了:基類中的 protected 成員可以在派生類中使用,而基類中的 private 成員不能在派生類中使用,下面是詳細(xì)講解。
public、protected、private 指定繼承方式
不同的繼承方式會(huì)影響基類成員在派生類中的訪問權(quán)限。
1) public繼承方式
基類中所有 public 成員在派生類中為 public 屬性;
基類中所有 protected 成員在派生類中為 protected 屬性;
基類中所有 private 成員在派生類中不能使用。
2) protected繼承方式
基類中的所有 public 成員在派生類中為 protected 屬性;
基類中的所有 protected 成員在派生類中為 protected 屬性;
基類中的所有 private 成員在派生類中不能使用。
3) private繼承方式
基類中的所有 public 成員在派生類中均為 private 屬性;
基類中的所有 protected 成員在派生類中均為 private 屬性;
基類中的所有 private 成員在派生類中不能使用。
通過上面的分析可以發(fā)現(xiàn):
1)?基類成員在派生類中的訪問權(quán)限不得高于繼承方式中指定的權(quán)限。例如,當(dāng)繼承方式為 protected 時(shí),那么基類成員在派生類中的訪問權(quán)限最高也為 protected,高于 protected 的會(huì)降級(jí)為 protected,但低于 protected 不會(huì)升級(jí)。再如,當(dāng)繼承方式為 public 時(shí),那么基類成員在派生類中的訪問權(quán)限將保持不變。
也就是說,繼承方式中的 public、protected、private 是用來指明基類成員在派生類中的最高訪問權(quán)限的。
2) 不管繼承方式如何,基類中的 private 成員在派生類中始終不能使用(不能在派生類的成員函數(shù)中訪問或調(diào)用)。
3) 如果希望基類的成員能夠被派生類繼承并且毫無障礙地使用,那么這些成員只能聲明為 public 或 protected;只有那些不希望在派生類中使用的成員才聲明為 private。
4) 如果希望基類的成員既不向外暴露(不能通過對(duì)象訪問),還能在派生類中使用,那么只能聲明為 protected。
注意,我們這里說的是基類的 private 成員不能在派生類中使用,并沒有說基類的 private 成員不能被繼承。實(shí)際上,基類的 private 成員是能夠被繼承的,并且(成員變量)會(huì)占用派生類對(duì)象的內(nèi)存,它只是在派生類中不可見,導(dǎo)致無法使用罷了。private 成員的這種特性,能夠很好的對(duì)派生類隱藏基類的實(shí)現(xiàn),以體現(xiàn)面向?qū)ο蟮姆庋b性。
下表匯總了不同繼承方式對(duì)不同屬性的成員的影響結(jié)果繼承方式/基類成員public成員protected成員private成員public繼承publicprotected不可見protected繼承protectedprotected不可見private繼承privateprivate不可見
由于 private 和 protected 繼承方式會(huì)改變基類成員在派生類中的訪問權(quán)限,導(dǎo)致繼承關(guān)系復(fù)雜,所以實(shí)際開發(fā)中我們一般使用 public。
【示例】演示類的繼承關(guān)系。
小明的年齡是15,考試成績(jī)?yōu)?2.5分,班級(jí)排名第4,TA喜歡乒乓球。
這是一個(gè)多級(jí)繼承的例子,Student 繼承自 People,Pupil 又繼承自 Student,它們的繼承關(guān)系為 People --> Student --> Pupil。Pupil 是最終的派生類,它擁有基類的 m_name、m_age、m_score、m_hobby 成員變量以及 setname()、setage()、sethobby()、gethobby()、setscore() 成員函數(shù)。
注意,在派生類 Pupil 的成員函數(shù) display() 中,我們借助基類的 public 成員函數(shù) gethobby() 來訪問基類的 private 成員變量 m_hobby,因?yàn)?m_hobby 是 private 屬性的,在派生類中不可見,所以只能借助基類的?public 成員函數(shù) sethobby()、gethobby() 來訪問。
在派生類中訪問基類 private 成員的唯一方法就是借助基類的非 private 成員函數(shù),如果基類沒有非 private 成員函數(shù),那么該成員在派生類中將無法訪問。
改變?cè)L問權(quán)限
使用 using 關(guān)鍵字可以改變基類成員在派生類中的訪問權(quán)限,例如將 public 改為 private、將 protected 改為 public。
注意:using 只能改變基類中 public 和 protected 成員的訪問權(quán)限,不能改變 private 成員的訪問權(quán)限,因?yàn)榛愔?private 成員在派生類中是不可見的,根本不能使用,所以基類中的 private 成員在派生類中無論如何都不能訪問。
using 關(guān)鍵字使用示例:
不過,我們使用 using 改變了它們的默認(rèn)訪問權(quán)限,如代碼第 21~25 行所示,將 show() 函數(shù)修改為 private 屬性的,是降低訪問權(quán)限,將 name、age 變量修改為 public 屬性的,是提高訪問權(quán)限。
因?yàn)?show() 函數(shù)是 private 屬性的,所以代碼第 36 行會(huì)報(bào)錯(cuò)。把該行注釋掉,程序輸出結(jié)果為:
我是小明,今年16歲,這次考了99.5分!