C/C++編程筆記:C++繼承——面向?qū)ο蟮闹匾δ?/h1>
一個(gè)類從另一個(gè)類派生屬性和特性的能力稱為繼承。繼承是面向?qū)ο缶幊痰淖钪匾δ苤弧?
子類:從另一個(gè)類繼承屬性的類稱為子類或派生類。?
超類:其屬性被子類繼承的類稱為基類或超類。?

本文分為以下子主題:
為什么以及何時(shí)使用繼承?
繼承方式
繼承類型
為什么以及何時(shí)使用繼承?
考慮一組車輛。您需要為公交車,汽車和卡車創(chuàng)建類。對(duì)于這三個(gè)類,方法fuelAmount(),capacity(),applyBrakes()都是相同的。如果我們創(chuàng)建這些類以避免繼承,則必須在三個(gè)類的每一個(gè)中編寫所有這些函數(shù),如下圖所示:?

您可以清楚地看到,上述過程導(dǎo)致相同代碼重復(fù)3次。這增加了錯(cuò)誤和數(shù)據(jù)冗余的機(jī)會(huì)。為了避免這種情況,將使用繼承。如果我們創(chuàng)建一個(gè)Vehicle類,并在其中編寫這三個(gè)函數(shù),并從Vehicle類繼承其余類,那么我們可以簡(jiǎn)單地避免數(shù)據(jù)重復(fù)并提高可重用性。請(qǐng)看下圖,其中三個(gè)類別是從車輛類別繼承的:

使用繼承,我們必須只編寫函數(shù)一次,而不是編寫函數(shù)三遍,因?yàn)槲覀円呀?jīng)從基類(Vehicle)繼承了其余三個(gè)類。
在C ++中實(shí)現(xiàn)繼承:要?jiǎng)?chuàng)建從基類繼承的子類,我們必須遵循以下語法。?
語法:?
類subclass_name:access_mode base_class_name{? //子類的主體};
在這里,subclass_name是子類的名稱,access_mode是您要繼承該子類的模式,例如:public,private等,而base_class_name是您要從其繼承子類的基類的名稱。 。?
注意:派生類不會(huì)繼承對(duì)私有數(shù)據(jù)成員的訪問。但是,它確實(shí)繼承了完整的父對(duì)象,該對(duì)象包含該類聲明的所有私有成員。

在上面的程序中,“孩子”類是從“父母”類公開繼承的,因此,“孩子”類的公共數(shù)據(jù)成員也將被“孩子”類繼承。
繼承方式
公共模式:如果我們從公共基類派生子類。然后,基類的公共成員將在派生類中成為公共成員,而基類的受保護(hù)成員將在派生類中成為受保護(hù)成員。?
保護(hù)模式:如果我們從保護(hù)的基類派生子類。然后,基類的公共成員和受保護(hù)的成員都將在派生類中受到保護(hù)。?
私有模式:如果我們從私有基類派生一個(gè)子類。然后,基類的公共成員和受保護(hù)的成員都將在派生類中變?yōu)樗接谐蓡T。?
注意:無法直接在派生類中訪問基類中的私有成員,而可以直接訪問受保護(hù)的成員。例如,在下面的示例中,類B,C和D都包含變量x,y和z。這只是訪問的問題。??

下表總結(jié)了上述三種模式,并顯示了以公共,保護(hù)和私有模式派生時(shí)子類中基類成員的訪問說明符:?

C ++中的繼承類型
1.單繼承:在單繼承中,一個(gè)類只能從一個(gè)類繼承。即一個(gè)子類只能被一個(gè)基類繼承。

語法:?
類subclass_name:access_mode base_class{
? //子類的主體
};

2.多重繼承:多重繼承是C ++的一項(xiàng)功能,其中一個(gè)類可以從多個(gè)類中繼承。即一個(gè)子類是從一個(gè)以上的基類繼承的。

語法:?
class subclass_name:access_mode base_class1,access_mode base_class2,....{
? //子類的主體
};
在此,基類的數(shù)量將以逗號(hào)(',')分隔,并且必須為每個(gè)基類指定訪問模式。?

3.多級(jí)繼承:在這種繼承類型中,從另一個(gè)派生類創(chuàng)建一個(gè)派生類。


4.層次繼承:在這種繼承中,一個(gè)基類繼承了多個(gè)子類。即,從一個(gè)基類創(chuàng)建一個(gè)以上的派生類。


5.混合(虛擬)繼承:混合繼承是通過組合多種類型的繼承來實(shí)現(xiàn)的。例如:組合層次繼承和多重繼承。?
下圖顯示了層次繼承和多重繼承的組合:


6.混合繼承的一種特殊情況:多路徑繼承:?
具有兩個(gè)基類并且這兩個(gè)基類具有一個(gè)公共基類的派生類稱為多路徑繼承。這種類型的繼承可能會(huì)引起歧義。?

考慮以下程序:??

在上面的示例中,ClassB和ClassC都繼承了ClassA,它們都具有ClassA的單個(gè)副本。但是,ClassD繼承了ClassB和ClassC,因此ClassD具有兩個(gè)ClassA副本,一個(gè)副本來自ClassB,另一個(gè)副本來自ClassC。?
如果我們需要通過ClassD的對(duì)象訪問ClassA的數(shù)據(jù)成員a,則必須指定從中訪問a的路徑,無論它是來自ClassB還是ClassC,bco'z編譯器都無法區(qū)分ClassA的兩個(gè)副本在ClassD中。
有兩種方法可以避免這種歧義:?
使用范圍解析運(yùn)算符避免歧義:?
使用范圍解析運(yùn)算符,我們可以手動(dòng)指定從中訪問數(shù)據(jù)成員a的路徑。
obj.ClassB::a = 10;?
obj.ClassC::a = 100;?
注意:仍然在ClassD中有ClassA的兩個(gè)副本。
使用虛擬基類避免歧義:?

根據(jù)上面的示例,ClassD只有ClassA的一個(gè)副本,因此,語句4將覆蓋語句3中給定的a的值。
以上就是今天的分享內(nèi)容!每天學(xué)點(diǎn)小知識(shí),希望對(duì)你有幫助~
文章來源丨極客(geeksforGeeks)
另外如果你想更好的提升你的編程能力,學(xué)好C語言C++編程!彎道超車,快人一步!筆者這里或許可以幫到你~
C語言C++編程學(xué)習(xí)交流圈子,【點(diǎn)擊進(jìn)入】微信公眾號(hào):C語言編程學(xué)習(xí)基地
分享(源碼、項(xiàng)目實(shí)戰(zhàn)視頻、項(xiàng)目筆記,基礎(chǔ)入門教程)
歡迎轉(zhuǎn)行和學(xué)習(xí)編程的伙伴,利用更多的資料學(xué)習(xí)成長(zhǎng)比自己琢磨更快哦!
編程學(xué)習(xí)書籍分享:
編程學(xué)習(xí)視頻分享: