1 什麼是繼承
物件導向的繼承關係指類之間的父子關係。用類圖表示如下:
2 為什麼要有繼承?/ 繼承的意義?
因為繼承是物件導向中程式碼複用的一種手段。通過繼承,可以獲取父類的所有功能,也可以在子類中重寫父類已有的功能 以及 新增父類中沒有的功能。
3 如何理解 子類是特殊的父類?
因為子類不僅繼承了父類所有的屬性與行為,而且在子類中還可以重寫父類已有的功能,以及新增自己的新屬性與新方法。這也就是說子類物件可以當作父類物件使用。
4 繼承的規則
1) 子類是特殊的父類
2) 子類物件可以直接初始化父類物件
3) 子類物件可以直接賦值給父類物件
5 繼承中的訪問級別
1)public:在類的內部和外部都可以訪問。
2)protected::可以在類的內部使用,不可以在類的外部直接使用。,但是存在繼承關係時,可以在子類中使用父類的protected的成員。
3)private:只可以在類的內部使用,不可以在類的外部使用。
注:類的內部:在當前類的作用域中(不包括子類的作用域);類的外部:類內部之外的作用域(包括子類的作用域)
問題1:子類是否可以直接訪問父類中的private成員(非公有成員)嗎?(No)
1)從物件導向理論的角度分析,可知子類擁有父類一切的屬性與行為,得出的結論:Yes
2)從c++的語法角度分析,可知外界不能訪問類的private成員,得出的結論:No
問題2:談談 protected關鍵字的存在的意義?
protected關鍵字是為繼承而存在的,這樣就可以在子類中訪問父類的protected成員,同時還不允許外界直接訪問父類中的protected成員。
問題3:在類中如何選擇類的訪問級別?--- 見下圖
6 繼承中的繼承方式
1)public 繼承方式 --- 父類成員在子類中保持原有的訪問級別。
2)protected 繼承方式 --- 父類中的公有成員在子類中變成了protected成員,其它不變。
3)private 繼承方式(預設) --- 父類成員在子類中變成了private成員
可歸納為:
結論:無論選擇哪種繼承方式,都不會影響子類訪問父類成員的級別
注:1) c++ 工程專案中只使用 public 繼承方式;
2) c++ 派生語言(jave,c#)只支援 public繼承方式;
3)protected、private 繼承方式帶來的複雜性遠大於其實用性;(捨棄不用)
用程式碼實現類圖中的功能:
程式碼如下:
1 #include <iostream> 2 #include <string> 3 #include <sstream> 4 5 using namespace std; 6 7 class Object 8 { 9 protected: 10 string mName; 11 string mInfo; 12 public: 13 Object() 14 { 15 mName = "Object"; 16 mInfo = ""; 17 } 18 inline string getName() 19 { 20 return mName; 21 } 22 inline string getInfo() 23 { 24 return mInfo; 25 } 26 }; 27 28 class Point : public Object 29 { 30 private: 31 int mX; 32 int mY; 33 public: 34 Point(int x = 0, int y = 0) 35 { 36 ostringstream oss; 37 38 mX = x; 39 mY = y; 40 mName = "Point"; 41 42 oss << "Point(" << mX << ", " << mY << ")"; 43 mInfo = oss.str(); 44 } 45 inline int getX() 46 { 47 return mX; 48 } 49 inline int getY() 50 { 51 return mY; 52 } 53 }; 54 55 class Line : public Object 56 { 57 private: 58 Point mP1; 59 Point mP2; 60 public: 61 Line(Point p1, Point p2) 62 { 63 mP1 = p1; 64 mP2 = p2; 65 mName = "Line"; 66 mInfo = "Line from " + p1.getInfo() + " to " + p2.getInfo(); 67 } 68 inline Point getStartPoint() 69 { 70 return mP1; 71 } 72 inline Point getEndPoint() 73 { 74 return mP2; 75 } 76 }; 77 78 int main(int argc, char const *argv[]) 79 { 80 Object obj; 81 cout << obj.getName() << endl; 82 cout << obj.getInfo() << endl << endl; 83 84 Point p1(1, 2); 85 Point p2(3, 4); 86 cout << p1.getName() << endl; 87 cout << p1.getInfo() << endl; 88 cout << p2.getName() << endl; 89 cout << p2.getInfo() << endl << endl; 90 91 Line line(p1, p2); 92 cout << line.getName() << endl; 93 cout << line.getInfo() << endl << endl; 94 95 return 0; 96 }