1、 類的繼承與派生基本概念ios
1. 概念:(繼承和派生是同一過程從不一樣角度看)函數
① 繼承:是新的類從已有類那裏獲得已有的特性。spa
② 派生:從已有類的基礎上新增本身的特性而產生新類的過程。設計
2.code
被繼承的已有類成爲基類(或父類);對象
派生出的新類成爲派生類(或子類);blog
直接參與派生出某類的基類稱爲直接基類;繼承
基類的基類甚至更高層的基類稱爲間接基類。(多級派生,生成類族)io
3. 目的:function
① 繼承的目的:實現設計與代碼的重用;
② 派生的目的:當新的問題出現,原有程序沒法解決(或不能徹底解決時),須要對原有程序進行改造。
4.
多繼承:一個派生類,能夠同時有多個基類;
單繼承:一個派生類只有一個直接基類。
① 單繼承時派生類的定義:(代碼)
語法:
class 派生類名:繼承方式 基類名
{
成員說明;
};
eg:
1 class Derived :public Base 2 { 3 public: 4 Derived(); 5 ~Derived(); 6 };
② 多繼承時派生類的定義:(代碼)
語法:
class 派生類名:繼承方式1 基類名1,繼承方式2 基類名2,...
{
成員說明;
};
注意:每個「繼承方式」,只用於限制對緊隨其後之基類的繼承。
eg:
1 class Derived :public Base1,private Base2 2 { 3 public: 4 Derived(); 5 ~Derived(); 6 };
5. 繼承方式
① 繼承方式關鍵字:
public(公有繼承)、protected(保護繼承)、private(私有繼承);
② 繼承方式規定了如何訪問從基類繼承的成員;
·基類公有成員=派生類公有成員,即派生類能夠像訪問自身的公有成員同樣訪問基類的公有成員;
·基類保護成員=派生類保護成員,即派生類能夠像訪問本身的保護成員同樣訪問基類的保護成員;
·基類私有成員:派生類的內部成員沒法直接訪問。派生類的使用者也沒法經過派生類對象直接訪問基類的私有成員。
總結:
派生類不能直接使用基類私有成員;
派生類能夠直接使用基類公有/保護成員;
③ 若是不顯式地給出繼承方式關鍵字,系統的默認值就認爲是私有繼承(private);
6. 派生類成員是指除了從基類繼承來的全部成員以外,新增長的數據和函數成員。
2、 派生類的生成過程
1. 步驟:吸取基類成員、改造基類成員、添加新的成員。
(1) 吸取基類成員:
① 默認狀況下派生類包含了所有基類中除構造函數和析構函數以外的全部成員;
② C++11規定能夠用using語句繼承基類構造函數;
③ 在定義派生類以後自動完成。
(2) 改造基類成員:
① 包括兩個方面:基類成員的訪問控制問題、對基類數據或函數成員的覆蓋和隱藏;
② 若是派生類聲明瞭一個和某基類成員同名的新成員(若是是成員函數,則參數表也要相同,參數不一樣的狀況屬於重載),派生的新成員就隱藏了外層同名成員。
這時在派生類中或者經過派生類的對象,直接使用成員名就只能訪問到派生類中聲明的同名成員,叫作同名隱藏。
(3) 添加新的成員:
① 須要在派生類中加入新的構造和析構函數。
3、 3種繼承方式
·包括:public(公有繼承)、protected(保護繼承)、private(私有繼承);
·不一樣繼承方式的影響主要體如今:
① 派生類成員對基類成員的訪問權限;
② 經過派生類對象對基類成員的訪問權限。
1. 公有繼承(最寬泛、最經常使用的一種繼承)
· 基類的public和protected成員:訪問屬性在派生類中保持不變;
· 基類的private成員:不可直接訪問。
▲訪問權限:
· 派生類中的成員函數:能夠直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員;
· 經過派生類的對象:只能訪問派生類的public成員(包括繼承的public成員)。
舉例說明(代碼以下):
1 #include <iostream> 2 using namespace std; 3 4 class Base 5 { 6 public: 7 Base(int nId) { mId = nId; } 8 int Id() { mId++; cout << mId << endl; return mId; } 9 protected: 10 int Num() { cout << 0 << endl; return 0; } 11 private: 12 int mId; 13 }; 14 15 class Child : public Base 16 { 17 public: 18 Child() : Base(7) { ; } 19 int newId() { return Id(); } //新增成員能夠訪問公有成員 20 int newNum() { return Num(); } //新增成員能夠訪問保護成員 21 //沒法訪問基類的私有成員 22 protected: 23 int y; 24 private: 25 int x; 26 }; 27 28 int main() 29 { 30 Child child; 31 child.Id(); //派生類的對象能夠訪問派生類繼承下來的公有成員 32 //child.GetNum(); //沒法訪問繼承下來的保護成員Num() 33 child.newId(); 34 child.newNum(); //派生類對象能夠訪問派生類的公有成員 35 //child.x; 36 //child.y; //沒法訪問派生類的保護成員y和私有成員x 37 return 0; 38 }
2. 私有繼承(最嚴格的一種繼承;不多使用)
· 基類的public和protected成員:都以private身份出如今派生類中;
· 基類的private成員:不可直接訪問。
▲訪問權限:
· 派生類中的成員函數:能夠直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員;
· 經過派生類的對象:不能直接訪問從基類繼承的任何成員。
舉例說明(代碼以下):
1 class Child : private Base 2 { 3 public: 4 Child() : Base(7) { ; } 5 int newId() { return Id(); } //能夠訪問基類的公有成員和保護成員 6 int newNum() { return Num(); } 7 protected: 8 int y; 9 private: 10 int x; 11 }; 12 13 int main() 14 { 15 Child child; 16 //child.Id();//派生類對象訪問不了繼承的公有成員,由於此時私有繼承時newId()已經爲private類型 17 //child.Num(); //派生類對象訪問不了繼承的保護成員,並且此時私有繼承時newNum()已經爲private類型 18 child.newId(); 19 child.newNum(); 20 return 0; 21 }
3. 保護繼承(介於公有和私有之間)
· 基類的public和protected成員:都以protected身份出如今派生類中;
· 基類的private成員:不可直接訪問。
▲訪問權限:
· 派生類中的成員函數:能夠直接訪問基類中的public和protected成員,但不能直接訪問基類的private成員;
· 經過派生類的對象:不能直接訪問從基類繼承的任何成員。
舉例說明(代碼以下):
1 class Child : protected Base 2 { 3 public: 4 Child() : Base(7) { ; } 5 int newId() { return Id(); } //能夠訪問基類的公有成員和保護成員 6 int newNum() { return Num(); } 7 protected: 8 int y; 9 private: 10 int x; 11 }; 12 13 int main() 14 { 15 Child child; 16 //child.Id();//派生類對象訪問不了繼承的公有成員,由於此時保護繼承時Id()已經爲protected類型 17 //child.Num(); //這個也訪問不了 18 child.newId(); 19 child.newNum(); 20 return 0; 21 }
注:protected成員的特色與做用
① 對創建其所在類對象的模塊來講,它與private成員的性質相同。毫不可能被其餘外部使用者(好比程序中的普通函數、與其類平行的其餘類)等訪問。
② 對於其派生類來講,它與public成員的性質相同。
③ 既實現了數據隱藏,又方便繼承,實現代碼重用。
舉例說明(代碼以下):
1 class A { 2 protected: 3 int x; 4 }; 5 class B :public A { //公有派生 6 public: 7 void function(); 8 }; 9 void B::function() { 10 x = 5; 11 }
注:若是B是A的派生類,B的成員函數只能經過B的對象訪問A中定義的protected成員,而不能經過A的對象訪問A的protected成員。
★總結:
不論是哪一種繼承方式,派生類中新增成員能夠訪問基類的公有成員和保護成員,沒法訪問私有成員。而繼承方式影響的是派生類繼承成員訪問屬性,而使用友元(friend)能夠訪問保護成員和私有成員。