在C++里,通過繼承和組合實現了代碼復用,使得開發效率提高,並且能夠通過代碼看到事物的關係 組合比繼承簡單,所以在寫代碼時先考慮能否組合,再來考慮繼承. 組合的特點 將其它類的對象作為當前類的成員使用 比如主機類,擁有 CPU/主板/記憶體/硬碟這4個對象成員,而這4個對象成員並沒有繼承主機類的特性和 ...
在C++里,通過繼承和組合實現了代碼復用,使得開發效率提高,並且能夠通過代碼看到事物的關係
組合比繼承簡單,所以在寫代碼時先考慮能否組合,再來考慮繼承.
組合的特點
- 將其它類的對象作為當前類的成員使用
比如主機類,擁有 CPU/主板/記憶體/硬碟這4個對象成員,而這4個對象成員並沒有繼承主機類的特性和行為
繼承的特點
- 新的類(子類)具有舊的類(父類)的屬性和行為
- 舊的類被稱為父類,也叫基類
- 新的類被稱為子類,也叫派生類(一個派生類也可以繼承多個基類)
- 子類可以添加新的屬性和行為(成員變數和成員函數),也可以重寫已有的屬性和行為
- 一個子類只繼承一個父類,便被稱為單繼承
- 一個子類若繼承多個父類,便被稱為多繼承
- 子類其實就是一個特殊的父類,比如:蘋果手機是手機,就是將蘋果手機當做一個特殊的父類對待
子類對象可以初始化父類對象,也可以賦值給父類對象,比如:
class Parent { int mValue; public: Parent() { mValue=10; } int Value() { return mValue; } }; class Child : public Parent { public: Child() { cout<<"I'm child"<<endl; } }; int main() { Child c;
cout<< c.Value() <<endl; //調用父類的成員函數 Parent p1 =c; //通過子類初始化父類 Parent p2; p2=c; //通過子類複製給父類 }
類的訪問級別之protected
大家都知道,類里private修飾的成員和函數,不能被外界直接訪問.
雖然子類擁有父類的屬性和行為,但是在子類里,也不能訪問父類的private私有成員
比如:
class Parent { int mValue; public: Parent(int i=0) { mValue=i; } int Value() { return mValue; } }; class Child : public Parent { public: Child() { cout<<mValue<<endl; //在子類中,訪問父類的private成員,將會編譯報錯 } };
所以類的訪問級別引入了新的關鍵字protected
protected的特性
- 修飾的成員不能被外界直接訪問
- 修飾的成員可以被子類(包括子類的子類)直接訪問, 也可以在本類內部直接訪問
有了protected的加入,定義類時,我們就需要仔細考慮成員的訪問級別,如下圖所示:
接下來做個綜合實例,組合與繼承
- 需要一個父類Object, 為子類Point和子類Line 提供name名字和info信息
- 由於線Line至少需要兩個點Point才能組成,所以Line子類內部需要通過Point子類來組合
如下圖所示:
開始寫代碼:
#include <iostream> #include <string> #include <sstream> using namespace std; class Object { protected: string mName; string mInfo; public: Object() { mName="Object"; mInfo=""; } string name() { return mName; } string info() { return mInfo; } }; class Point : public Object { protected: int x; //坐標 int y; public: Point(int x=0,int y=0) { ostringstream s; this->x =x; this->y =y; s<<"P("<<x<<","<<y<<")"; //坐標信息 mName="Point"; mInfo=s.str(); } }; class Line : public Object { private: Point mP1; Point mP2; public: Line(Point p1,Point p2) { ostringstream s; mP1 =p1; mP2 =p2; s<<"Line from " <<p1.info() <<" to "<<p2.info(); //線的信息 mName ="Line"; mInfo =s.str(); } }; int main() { Point p1(2,3); Point p2(6,3); Line L(p1,p2);
/*列印點的信息*/ cout<<p1.name()<<":"<<endl; cout<<p1.info()<<endl; /*列印線的信息*/ cout<<L.name()<<":"<<endl; cout<<L.info()<<endl; return 0; }
運行列印:
Point: P(2,3) Line: Line from P(2,3) to P(6,3)
接下來來學習: 23.C++- 繼承的多種方式、顯示調用父類構造函數、父子之間的同名函數、虛函數