1

值得思考的问题

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

思考过程

  • 根据面向对象理论:

clipboard.png

  • 根据C++ 语法:

clipboard.png

clipboard.png

编程实验: 继承中的访问级别

#include <iostream>

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()
{
    Child c;

    return 0;
}
输出:
test.cpp: In member function ‘int Child::addvalue(int)’:
test.cpp:8: error: ‘int Parent::mv’ is private
test.cpp:26: error: within this context
test.cpp:8: error: ‘int Parent::mv’ is private
test.cpp:26: error: within this context

继承中的访问级别

  • 面向对象中的访问级别不只是 public 和 private
  • 可以定义 protected 访问级别
  • 关键字 protected 的意义

    • 修饰的成员不能被外界直接访问
    • 修饰的成员可以被子类直接访问

编程实验: protected 初体验

#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 = 1000;  // Error

    return 0;
}
输出:
p.mv = 100
c.mv = 100
c.mv = 150

定义类时访问级别的选择

clipboard.png

组合与继承的综合实例

clipboard.png

  • point 继承于 Object
  • Line 继承于 Object
  • 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
{
private:
    int mX;
    int mY;
public:
    Point(int x = 0, int y = 0)
    {
        mX = x;
        mY = y;
        
        mName = "Point";
        
        ostringstream oss;
        oss << "p(" << mX << "," << mY << ")";
        mInfo = oss.str();
    }
    int getX()
    {
        return mX;
    }
    int getY()
    {
        return mY;
    }
};

class Line : public Object
{
private:
    Point mP1;
    Point mP2;
public:
    Line(Point p1, Point p2)
    {
        mP1 = p1;
        mP2 = p2;
        
        mName = "Line";
        
        ostringstream oss;
        oss << "Line from " << mP1.info() << " to " << mP2.info();
        mInfo = oss.str();
    }
};

int main()
{
    Object o;
    
    cout << o.name() << endl;
    cout << o.info() << endl;
    
    cout << endl;
    
    Point p1(1, 2);
    Point p2(3, 4);
    
    cout << p1.name() << endl;
    cout << p1.info() << endl;
    
    cout << endl;
    
    Line l(p1, p2);
    
    cout << l.name() << endl;
    cout << l.info() << endl;
    
    return 0;
}
输出:
Object


Point
p(1,2)

Line
Line from p(1,2) to p(3,4)

小结

  • 面向对象中的访问级别不只是 public 和 private
  • protected 修饰的成员不能被外界所访问
  • protected 使得子类能够访问父类的成员
  • protected 关键字是为了继承而专门设计的
  • 没有 protected 就无法完成真正意义上的代码复用

以上内容参考狄泰软件学院系列课程,请大家保护原创!


TianSong
734 声望138 粉丝

阿里山神木的种子在3000年前已经埋下,今天不过是看到当年注定的结果,为了未来的自己,今天就埋下一颗好种子吧