子类是否可以直接访问父类的私有成员?
思考过程:
示例:
可以看到27行在子类中直接访问父类的私有成员就报错了。
示例:
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; 36 37 // p.mv = 1000; // error 38 39 Child c; 40 41 cout << "c.mv = " << c.value() << endl; 42 43 c.addValue(50); 44 45 cout << "c.mv = " << c.value() << endl; 46 47 // c.mv = 10000; // error 48 49 return 0; 50 }
将mv的访问级别改为protected,编译就不会报错了。
结果如下:
上述程序中的第47行是错误的,因为mv是protedted的,而main函数是类的外部,不能直接访问。
思考:
为什么面向对象中需要protected?
面向对象来源于生活,对于一个人来说有一些信息是公开的,例如名字。因此,名字就可以是public的。还有一些信息是隐私,不想往外界知道,例如身高,这就是private的。除此之外,还有一些其他的信息可以公开给一部分的人,例如工资,我们不想让外人知道,但是想让家人知道。这就是protected的。它的访问权限介于public和private之间。有了这个访问级别,我们可以更好的用程序去描述生活中的示例。
protected的引入是必须的。 没有这个访问级别,面向对象就是不完善的。
protected在某中角度也可以说专门是为了在子类中访问父类的私有成员而引入的。
定义类时访问级别的选择:
结论:可以说protected就是专门为继承而设计的。
组合与继承的综合示例:
两个点确定一条直线,Line这个类需要组合两个Point对象。
示例程序:
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 string name() 19 { 20 return mName; 21 } 22 string info() 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 s; 37 38 mX = x; 39 mY = y; 40 mName = "Point"; 41 42 s << "P(" << mX << ", " << mY << ")"; 43 44 mInfo = s.str(); 45 } 46 int x() 47 { 48 return mX; 49 } 50 int y() 51 { 52 return mY; 53 } 54 }; 55 56 class Line : public Object 57 { 58 private: 59 Point mP1; 60 Point mP2; 61 public: 62 Line(Point p1, Point p2) 63 { 64 ostringstream s; 65 66 mP1 = p1; 67 mP2 = p2; 68 mName = "Line"; 69 70 s << "Line from " << mP1.info() << " to " << mP2.info(); 71 72 mInfo = s.str(); 73 } 74 Point begin() 75 { 76 return mP1; 77 } 78 Point end() 79 { 80 return mP2; 81 } 82 }; 83 84 int main() 85 { 86 Object o; 87 Point p(1, 2); 88 Point pn(5, 6); 89 Line l(p, pn); 90 91 cout << o.name() << endl; 92 cout << o.info() << endl; 93 94 cout << endl; 95 96 cout << p.name() << endl; 97 cout << p.info() << endl; 98 99 cout << endl; 100 101 cout << l.name() << endl; 102 cout << l.info() << endl; 103 104 return 0; 105 }
mName和mInfo可以被子类访问,因此定义为protected的,其他的类似。
小结: