C++:12.繼承與派生

爲了支持代碼的複用,繼承與派生在C++中就顯得十分重要。


繼承與派生:

當定義一個新的類 B 時,如果發現類 B 擁有某個已寫好的類 A 的全部特點,此外還有類 A 沒有的特點,那麼就不必從頭重寫類 B,而是可以把類 A 作爲一個“基類”(也稱“父類”),把類 B 寫爲基類 A 的一個“派生類”(也稱“子類”)。這樣,就可以說從類 A “派生”出了類 B,也可以說類 B “繼承”了類 A。

基類的所有成員都自動稱爲派生類的成員。派生類可以在其基礎上添加和修改

舉個栗子:學生類作爲基類,成員函數中打印函數可以打印姓名、性別。本科生類作爲派生類,成員函數中要多打印一個專業。那麼可以在本科生類中寫一個與學生類中打印函數同名的函數,先調用學生類中的打印函數,在單獨打印專業這一信息。通過派生類對象訪問同名成員,除非特別指明,否則訪問的就是派生類的成員,這種情況叫“覆蓋”,即派生類的成員覆蓋基類的同名成員。

派生類對象佔用的存儲空間大小  =  基類對象佔用存儲空間大小  +  派生類對象自身成員變量佔用存儲空間大小。

類與類之間的關係有兩種:組合和繼承。組合指的是A是B的一部分。繼承指的是A是B的一種。


protected:

之前一直使用的是public與private。protected修飾的是保護成員,它的可訪問範圍介於public與private之間。

設置protected的目的:無論派生類是用何種方式繼承的基類,基類中的私有成員在派生類中都是無法訪問的。但是派生類的成員函數又確實需要經常訪問基類成員。所以我們將它設置爲保護成員,既可以起到隱藏的目的,又可是讓派生類訪問它。(保護成員可以在派生類訪問,但不能在其他地方訪問。)

如果不寫繼承方式:最好還是寫上!

派生類用struct定義,默認繼承方式就是public。派生類用class定義,默認繼承方式就是private。


派生類的構造函數和析構函數:

由於派生類中包含基類成員,所以在執行派生類構造函數的時候,都會先執行基類的構造函數(在構造函數的參數列表中,如果不在初始化列表中,寫在內部,它的意思就先構造派生類了,肯定是錯的)。如果對此不做說明,編譯器會調用基類的無參構造函數,如果沒有無參構造函數,就會報錯。

析構函數的調用依舊滿足:先構造的後析構,後構造的先析構的特點。

多層次的派生:

A類 派生 B類,B類 派生 C類。

則 A類 是 B類 的直接基類,B類 是 C類 的直接基類,A類 是 C類 的間接基類。

在 C類 寫派生關係的時候,只寫直接基類 B類,不寫間接基類 A類。

調用構造函數的時候會先構造最上面的基類,之後依次往下。

當組合與派生同時使用:

先調用基類的構造函數,再按照成員對象的定義順序執行各自的構造函數。


基類與派生類賦值(初始化)規則:

  • 派生類對象可以賦值給基類對象。
  • 派生類對象可以用來初始化基類引用。
  • 派生類的指針可以賦值給基類的指針。

結論:繼承結構中,默認支持從下到上的轉換,反過來不行的。

理解一下:派生類包含基類,派生類是個大圈裏面有個小圈是基類。大的(派生類)給小的(基類)賦值可以,你小的(基類)給大的(派生類)只能賦一部分,剩下的就浪費了所以不合適。      雖然說大的(派生類指針)可以給小的(基類指針)賦值,但不屬於小的(基類指針)那一部分,小的(基類指針)也是無法訪問的。(也就是說不能通過基類指針訪問基類沒有而派生類中有的成員。

還有一點:雖然小的(基類指針)不能賦值給大的(派生類指針),但你要強制類型轉換,編譯器當然也會認可。但這種情況下需要保證那個基類指針本身就指向一個派生類對象。不然會出錯。慎用!!!!


基類與派生類同名成員的訪問:

同名成員方法的關係:重載、隱藏、覆蓋

重載

在基類或者派生類同一個類作用域當中的,函數名相同,參數列表不同。

隱藏

方法分佈在基類和派生類中

只要方法名字相同(無論參數個數或參數類型是否相同),就說派生類的同名方法把基類的同名方法給隱藏了。

覆蓋

方法分佈在基類和派生類中

基類的方法是虛函數,派生類的方法和基類的虛函數,返回值相同,函數名相同,參數列表也相同。那麼就會用派生類的函數覆蓋掉基類的虛函數。在虛函數表中進行覆蓋!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章