1. 繼承介紹
上一篇中,已介紹了複合類,複合類只是C++中建立複雜類的主要方法之一。
本篇中,介紹另外一種方法,即類的繼承。
與複合類通過結合和串連其他對象進行建立新的對象;繼承,通過直接擷取其他對象的屬性和行為來建立新的對象,同時對其進行擴充和特殊化。
如你繼承你父母的基因;技術的更新換代;C++語言繼承了C語言的許多特性,同時也增加了自己的特性等等。
父類(基類)-被繼承的對象;子類(衍生類)-繼承形成的對象。
繼承的關係是一種is-a關係,即子類可以當作父類進行處理;
通常,子類繼承了父類的所有屬性,子類可以定義或重定義繼承得來的屬性,增加新的屬性,甚至隱藏屬性。
C++中需要繼承的原因:
1)OOP的最基本的特性之一就是代碼的重用性;但是已有代碼通常不能恰好滿足需要,通常的方法是修改已有代碼,但是這不是最好的辦法。
2)較好的方法之一,是拷貝已有的代碼,然後進行修改;但這方法有許多缺點:A)很危險,因為拷貝代碼會出現錯漏;B)修改已有代碼,你必須從根本上去理解已有的代碼,如果已有代碼很複雜就很困難了;C)修改和修正代碼之後,必須維持原有代碼的同步,維護量很大。
3)所以,繼承在大多數的問題中,是一個有效方法;繼承允許你利用現有的代碼,達到自己的要求。
2. C++基本繼承
繼承在C++中,通常出現在類之間。當一個類繼承其他的類,衍生類就會繼承父類的變數和函數;這些變數和函數就成為這個類的一部分。
一個Person類:
Person類包含了人的基本資料;
一個BaseballPlayer類:
BaseballPlayer也需要包含姓名、年齡和性別等資訊;但剛才已定義了一個Person類,所以BaseballPlayer可以繼承Person類:
現在,測試一下衍生類BaseballPlayer:
一個Emploee衍生類:
繼承鏈:
通過繼承鏈,我們可以定義一系列的可重用的代碼。
小結:通過繼承,我們可以擷取父類的資訊,而不用去重新定義;當父類發生改變,子類也會相應改變;
3. 衍生類的構造順序
在上一節中,類可以從其他類中繼承變數和函數;這節主要講衍生類的構造順序。
下面是2個新類:
Drived類包含了2部分:一部分是基類,一部分是衍生類的。
在執行個體化中:
Base是非衍生類,只需單單執行自己的預設建構函式;Drived是繼承Base的衍生類,執行個體化的過程中,需執行Base和自己的構造部分;
衍生類在構造過程中,遍曆繼承樹,構造每個繼承的部分。
現在,以下示範了衍生類的構造順序:
列印的結果是:
如以上所示,衍生類構造時,首先是構造基類部分;畢竟沒有父類,不存在子類;子類使用父類中的變數和函數,而父類不瞭解子類,首先構造基類,保證了子類可以使用已初始化的變數。
2)繼承鏈中的構造順序
列印的結果是:
如上所示,繼承鏈中的構造順序,是居於最高層的基類首先構造,逐步沿著繼承樹構造。
4. 衍生類的建構函式和初始化
本章節主要詳細講解衍生類的建構函式和初始化的規則。
在上一節中:
對於Base的執行個體化,簡單就如:
因為Base是非衍生類,只需考慮自己的成員的初始化;
構造的過程是:
A)為cBase分配記憶體空間;B)合適的Base建構函式調用;C)初始化列表初始設定變數;D)執行建構函式;E)返回給調用者。
而對於Drived的執行個體化,如:
構造過程是:
A)為cDrive分配記憶體空間,足夠承載Base部分和Drived部分;B)合適的Drived建構函式調用;C)Base對象首先構造;
D)初始化列表初始設定變數;E)執行建構函式;F)返回給調用者。
衍生類和非衍生類的主要區別就是,衍生類必須首先構造基類對象。