32 继承中的访问级别

1 问题

  • 子类是否可以直接访问父类的私有成员

    • 根据面对对象理论:子类拥有父类的一切属性和行为 => 子类能够直接访问父类的私有成员
    • 根据 C++ 语法:外界(子类也是父类的外界)不能直接访问类的 private 成员 => 子类不能直接访问父类的私有成员
  • 示例:继承中的访问级别

    • Dmeo

      #include <iostream>
      #include <string>
      
      using namespace std;
      
      class Parent
      {
      private:
          int mv;
      public:
          Parent()
          {
              mv = 100;
          }
          
          int value()
          {
              return mv;
          }
      };
      
      class Child : public Parent
      {
      public:
          int addValue(int v)
          {
              mv = mv + v;    // ???? 如何访问父类的非公有成员
          }
      };
      
      int main()
      {   
          return 0;
      }
      
    • 编译

      test.cpp: In member function ‘int Child::addValue(int)’:
      test.cpp:8:13: error: ‘int Parent::mv’ is private
               int mv;
                   ^
      test.cpp:23:13: error: within this context
                   mv = mv + v;
      

2 继承中的访问级别

  • 面对对象中的访问级别不只是 publicprivate

  • 可以定义 protected 访问级别

  • 关键字 protected 的意义

    • 修饰的成员不能被外界直接访问
    • 修饰的成员可以被子类直接访问
  • 示例:protected 使用

    • Demo

      #include <iostream>
      
      using namespace std;
      
      class Parent
      {
      protected:
          int mv;
      public:
          Parent()
          {
              mv = 100;
          }
          
          int value()
          {
              return mv;
          }
      };
      
      class Child : public Parent
      {
      public:
          int addValue(int v)
          {
              mv = mv + v;    
          }
      };
      
      int main()
      {   
          Parent p;
          
          cout << "p.mv = " << p.value() << endl;
          
          p.mv = 1000;    // error:外界无法访问
          
          Child c;
          
          cout << "c.mv = " << c.value() << endl;
          
          c.addValue(50);
          
          cout << "c.mv = " << c.value() << endl;
          
          c.mv = 10000;  // error:外界无法访问
          
          return 0;
      }
      
    • 编译运行

      test.cpp: In function ‘int main()’:
      test.cpp:8:13: error: ‘int Parent::mv’ is protected
               int mv;
                   ^
      test.cpp:33:7: error: within this context
           p.mv = 1000;
             ^
      test.cpp:8:13: error: ‘int Parent::mv’ is protected
               int mv;
                   ^
      test.cpp:41:7: error: within this context
           c.mv = 1000;
             ^
      
  • 问题:为什么面对对象中需要 protected

    • protected 关键字是为了继承而专门设计的
    • 没有 protected 就无法完成真正意义上的代码复用
  • 示例:组合和继承的综合实例

    • Dmeo

      #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
      {
      private:
          int mX;
          int mY;
      public:
          Point(int x = 0, int y = 0)
          {
              ostringstream s;
              
              mX = x;
              mY = y;
              mName = "Point";
              
              s << "P(" << mX << ", " << mY << ")";
              
              mInfo = s.str();
          }
          int x()
          {
              return mX;
          }
          int y()
          {
              return mY;
          }
      };
      
      class Line : public Object
      {
      private:
          Point mP1;
          Point mP2;
      public:
          Line(Point p1, Point p2)
          {
              ostringstream s;
              
              mP1 = p1;
              mP2 = p2;
              mName = "Line";
              
              s << "Line from " << mP1.info() << " to " << mP2.info();
              
              mInfo = s.str();
          }
          Point begin()
          {
              return mP1;
          }
          Point end()
          {
              return mP2;
          }
      };
      
      int main()
      {   
          Object o;
          Point p(1, 2);
          Point pn(5, 6);
          Line l(p, pn);
          
          cout << o.name() << endl;
          cout << o.info() << endl;
          
          cout << endl;
          
          cout << p.name() << endl;
          cout << p.info() << endl;
          
          cout << endl;
          
          cout << l.name() << endl;
          cout << l.info() << endl;
          
          return 0;
      }
      
    • 编译运行

posted @ 2020-10-30 19:36  nxgy  阅读(81)  评论(0编辑  收藏  举报