4. 覆盖

覆盖是指子类实现了同名,参数列表也完全相同的成员函数,在子类对象调用该方法时,实际调用的是子类的方法(父类的方法不会被调用),此种现象成为制覆盖(或屏蔽)。

子类成员函数的调用规则是向上查找规则,即子类先查找自己是否有这个成员函数,如果没有就查找父类,如果再没有就查找父类的父类... 以此类推。都没有找到则报错。

示例

父类 Point 实现了 getAreagetLength 两个成员函数,子类也是现实了同样名称和参数的成员函数进行了覆盖。此时父类对象调用父类的成员函数,子类则调用子类的成员函数。

// filename: inherit.cpp
#include <iostream>

using namespace std;

#define PI (3.1415926)
// 点类(描述一个点的位置,面积等信息)
class Point {
    public:
        Point(float ax=0, float ay=0):x(ax), y(ay) {
            cout << "Point(" << x << "," << y << ")\n";
        }
        void info(void) {
            cout << "点(" << x << "," << y << ")\n";
        }
        void moveTo(float new_x, float new_y) {
            x = new_x; y = new_y;
        }
        float getArea(void) { // 获取图形面积
            return 0;
        }
    public:
        float x;
        float y;
};
// 圆类(描述圆的位置、半径、面积等信息)
class Circle : public Point {
    public:
        Circle(float ax, float ay, float radius)
            : Point(ax, ay), r(radius) {
            //  x = ax; y = ay; r = radius;
            cout << "Circle(" << x << "," << y << "," << r << ")\n";
        }
        void info(void) {
            cout << "圆(" << x << "," << y << "," << r << ")\n";
        }
        float getArea(void) {
            return PI*r*r;
        }
    public:
        float r; // 半径
};

int main(int argc, char * argv[]) {
    Point p1(3, 5);
    Circle c1(4, 6, 10);

    cout << "sizeof(p1)" << sizeof(p1) << endl;
    cout << "sizeof(c1)" << sizeof(c1) << endl;
    c1.info();
    p1.info();
    p1.moveTo(100, 105);
    // 子类对象不存在moveTo,则调用父类的方法
    c1.moveTo(200, 210);
    p1.info();
    c1.info();
    cout << "p1的面积" << p1.getArea() << endl;
    cout << "c1的面积" << c1.getArea() << endl;
    cout << "程序结束!" << endl;
    return 0;
}

可见虽然 c1 对象的父类是 Point 类。但 c1.getArea() 则调用自己的 Circle 类自己的 getArea 成员函数。