1,子類是否可以直接訪問父類的私有成員?
2,根據面向對象理論:
根據 C++ 語法:
3,繼承中的訪問級別編程實驗:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Parent 7 { 8 private: 9 int mv; 10 11 public: 12 Parent() 13 { 14 mv = 100; 15 } 16 17 int value() 18 { 19 return mv; 20 } 21 }; 22 23 class Child : public Parent // Child 雖然是 Parent 的子類,但是嚴格意義上來說,它絕對是 Parent 的外部,因此 Parent 不可以訪問 Parent 類的私有成員; 24 { 25 public: 26 int addValue(int v) 27 { 28 mv = mv + v; // 這里訪問了兩次 mv,編譯器則顯示了兩次編譯錯誤,在同一個地方;如何訪問父類的非公有成員? 29 } 30 }; 31 32 int main() 33 { 34 return 0; 35 }
4,繼承中的訪問級別:
1,面向對象中的訪問級別不只是 public 和 private:
2,可以定義 protected 訪問級別;
3,關鍵字 protected 的意義;
1,修飾的成員不能被外界直接訪問;
2,修飾的成員可以被子類直接訪問;
5,protected 初體驗編程實驗:
1 #include <iostream> 2 #include <string> 3 4 using namespace std; 5 6 class Parent 7 { 8 protected: 9 int mv; 10 public: 11 Parent() 12 { 13 mv = 100; 14 } 15 16 int value() 17 { 18 return mv; 19 } 20 }; 21 22 class Child : public Parent 23 { 24 public: 25 int addValue(int v) 26 { 27 mv = mv + v; 28 } 29 }; 30 31 int main() 32 { 33 Parent p; 34 35 cout << "p.mv = " << p.value() << endl; // 100; 36 37 // p.mv = 1000; // error,除子類之外的外界不能訪問; 38 39 Child c; 40 41 cout << "c.mv = " << c.value() << endl; // 100; 42 43 c.addValue(50); 44 45 cout << "c.mv = " << c.value() << endl; // 150; 46 47 // c.mv = 10000; // error,除子類之外的外界不能訪問; 48 49 return 0; 50 }
6,為什么面向對象中需要 protected ?
1,所有的開發者應該都有一個架構師德夢想,架構師需要具備的一個素質就是設計能力,我們在做開發的時候,也許系統需要這個功能、也許不需要,究竟需不需要呢?一個系統中並不是功能越多越好,因此我們必須要有設計能,學習過程中要多思考;
2,從生活中入手來思考,女孩子整容否、男孩子尿床、同性戀否,這些信息就是 private 的,生活中的工資是隱私,但是家人可以知道,這是就是 protected;
3,protected 的引入是必須的、絕對的,沒有它的引入,面向對象就是不完善的;
4,其他的面向對象語言中如 Java、C# 等,它們當中的訪問權限不止三種;
7,定義類時訪問級別的選擇:
1,左右分支的不同之處在於,是否會被繼承,這也是 protected 選擇與否的根本依舊;
8,組合與繼承的綜合實例:
1,這張圖中 Object 這個類就是用來被繼承的;
2,Line 這個類組合了 Point 這個類;
3,綜合實例編程實驗:
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 13 public: 14 Object() 15 { 16 mName = "Object"; 17 mInfo = ""; 18 } 19 20 string name() 21 { 22 return mName; 23 } 24 25 string info() 26 { 27 return mInfo; 28 } 29 }; 30 31 class Point : public Object // 點這個類不需要被繼承; 32 { 33 private: 34 int mX; 35 int mY; 36 37 public: 38 Point(int x = 0, int y = 0) 39 { 40 ostringstream s; 41 42 mX = x; 43 mY = y; 44 mName = "Point"; 45 46 s << "P(" << mX << ", " << mY << ")"; 47 48 mInfo = s.str(); 49 } 50 51 int x() 52 { 53 return mX; 54 } 55 56 int y() 57 { 58 return mY; 59 } 60 }; 61 62 class Line : public Object // 不會被繼承; 63 { 64 private: 65 Point mP1; 66 Point mP2; 67 68 public: 69 Line(Point p1, Point p2) // 這里編譯錯誤,因為要調用默認構造函數,但是 Point 已經定義了構造函數,此刻可以采用賦默認值的方式; 70 { 71 ostringstream s; 72 73 mP1 = p1; 74 mP2 = p2; 75 mName = "Line"; 76 77 s << "Line from " << mP1.info() << " to " << mP2.info(); 78 79 mInfo = s.str(); 80 } 81 82 Point begin() 83 { 84 return mP1; 85 } 86 87 Point end() 88 { 89 return mP2; 90 } 91 }; 92 93 int main() 94 { 95 Object o; 96 Point p(1, 2); 97 Point pn(5, 6); 98 Line l(p, pn); 99 100 cout << o.name() << endl; // 單元測試;Object 101 cout << o.info() << endl; // 單元測試;“ ” 102 103 cout << endl; 104 105 cout << p.name() << endl; // 單元測試;Point 106 cout << p.info() << endl; // 單元測試;p(1, 2) 107 108 cout << endl; 109 110 cout << l.name() << endl; // Line 111 cout << l.info() << endl; // Line from p(1, 2) to p(5, 6) 112 113 return 0; 114 }
9,小結:
1,面向對象中的訪問級別不只是 public 和 private;
2,protected 修飾的成員不能被外界所訪問;
3,protected 使得子類能夠訪問父類的成員;
1,子類繼承父類后,子類和父類中相同的代碼各有一套,分別存儲使用的。
4,protected 關鍵字是為了繼承而專門設計的;
5,沒有 protected 就無法完成真正意義上的代碼復用;
1,因為 private 不能繼承,而 public 不用繼承,但是有些信息又是介乎兩者之間的;