繼承是麵向對象語言提供的一個重要方法,是傳統的結構程序語言所不具有的,它提供了組織程序和重複使用代碼的強有力的手段。繼承可以清晰自然地表達實際問題中的分類結構或層次結構。
8.1繼承的概念
繼承通過對一個已存在的類進行特殊化來建立一個新的類。已存在的類稱為基類(也稱為父類或超類),新建立的類稱為派生類(也稱為子類)。派生類不但繼承了基類所有的成員變量和成員函數,而且可以添加新的成員變量和成員函數,改變所繼承的成員函數的語義。
我們通過一個例子來具體說明繼承的概念。
例8.1我們定義兩個類:類Location用來描述“位置”的概念,類Rectangle用來描述“矩形”的概念。
在類Location中,數據成員*和7分別記錄“位置”的水平坐標和垂直坐標。成員函數GetX()和GetY()用來取得水平坐標和垂直坐標的值。
在類Rectangle中,除了要有記錄位置的數據成員x和y外,還要有記錄矩形長和寬的數據成員width和heiit。成員函數GetWidth()和GetHeight().用來取得矩形長和寬的值。
觀察類Location和Rectangle,我們發現二者存在一定的關係:類Rectangle除了擁有類Location的所有成員外,同時還具有自己特殊的成員。實際上,我們在畫一個矩形時,首先舉確定該矩形的位置,然後再給出長和寬。於是,我們可以在類Location和Rectangle之間建立一種繼承關係。
它的含義是:類Rectangle是由類Location公有派生出來的。這是Visual C++表達繼承關係的句法表達式,關鍵字public用來規定基類Location中的成員在派生類Rectangle中的使用權限,詳細說明請見下一節。
在這個例子中,我們把被繼承的類Location稱為基類,通過繼承關係定義出來的類Rectangle稱為派生類。換一句話說,類Location是類Rectangle的基類,類Rectangle是類Location的派生類。
由於每一個派生類都是基類成員與自身成員的集合,所以,在內存中派生類對象的前一部分是它的基類成員,後一部分是派生類的自身成員。
8.2派生類
通過繼承關係,我們可以由一個基類定義出一個新類即派生類。
具體說明如下:
1.花括號中的部分用來定義派生類新增成員,或是基類已經有的但是在派生類重新修改過的成員。
2.“訪問控製”用來規定基類中的成員在派生類中的訪問權限。訪問控製可以是關鍵字public、private或protected0。
blic,稱這種繼承關係為公有派生,派生類為基的公有派生類。使用關鍵字private,稱這種繼承關係為私有派生,派生類稱為類的私有派生類。使用關鍵字protected,稱這種繼承關係為保護派生,派生類稱為基類的保護派生,。
4.在定義派生類時,訪問控製可以省略,缺省時表示私有派生。
5.派生類是基類成員與自身成員的集合。訪問派生類中自身的成員,可遵循一般規則,但訪問繼承來的基類成員時,要受到一定的限製,這要由成員訪問控製和派生類訪問控製同時決定,在下麵將要講到。
6.定義一個類時,可以使用訪問說明符來規定該類中成員的訪問權限,但引人繼承機製以後,從基類繼承過來的成員訪問權限發生了很大變化。有些成員是可繼承的(至少在成員函數中可以訪問它),而有些成員是不可繼承的,即程序的任何地方都不可訪問它(即使是該類自身成員函數也不能訪問它),我們把這些不可繼承的成員“不可訪問的成員”。
“不可訪問的成員”是比私有成員訪問限製還要嚴格的成員。一個不可訪問的成員不僅不能在程序的其他地方訪問,即使是該類自身成員函數也不能訪問它。
“不可訪問的成員”隻有通過類的派生獲得。在以後的學習過程中,大家會逐漸領悟到這一點。
一、公有派生類
使用關鍵字public定義的派生類,稱為基類的公有派生類。
在公有派生類中,基類的公有成員與保護瑪員成為派生類的公有成員與保護成員,基類的私有成員成為派生類的不可訪問成員。
因此,在程序中,我們可以通過派生類對象訪問基類的公有成員,但不能訪問類中的私有成員。
本例中,由於派生類Rectangle是公有派生,基類Location中的私有成員成為派生類的不可訪問的成員,基類Location中的公有成員成為派生類Rectangle的公有成員。
在函數main()中,我們創建了一個派生類的對象ob,可以通過該對象ob訪問派生類的公有成員,包括從基類繼承過來的公有成員:
二、私有派生
使用關鍵字private定義的派生類,稱為基類的私有派生類。
在私有派生類中,基類的公有成員與保護成員成為派生類的私有成員,基類的私有成員成為派生類的不可訪問成員。
因此,在程序中,不能通過派生類對象訪問從基類繼承來的任何成員。
本例中,由於派生類Rectangle是私有派生,基類Location中的公有成員成為派生類Rectangle的私有成員。
在函數main()中,我們創建了一個派生類的對象ob,但不能通過該對象ob訪問從基類繼承過來的任何成員。
注意,在私有派生中基類的公有成員成為派生類的私有成員,所以,隻能在派生類的成員函數內訪問。
三、在派生類的成員函數中訪問基類成員
在派生類中,基類成員成為派生類的一部分,由於受訪問權限的限製,使得在程序中通過派生類對象訪問這些基類的成員受到一定的限製。同樣,在派生類的成員函數中訪問基類成員,也要遵守一定的規則:
1.在派生類的成員函數中不能訪問基類的私有成員。
2.在派生類的成員函數中可以訪問基類的公有成員。
是錯誤的,因為x和y是基類Location中的私有成員,不能被派生類的成員函數訪問。不過,我們可以通過公有成員函數GetX()和GetY()來實現同樣的目的。