上一篇文章中,我们看到了简单的赋值兼容模型,将子类赋值给父类对象时,调用共有的同名接口时,调用的依然还是父类的成员函数。在 C++ 中,有一个总要的概念,那就是多态。通过父类提供一些虚函数,让子类继承下去并实现为另外的功能,然后将子类对象的地址赋值给父类的对象指针。这样再次使用父类的指针调用共有同名接口时,你会发现它竟然调用的是子类的方法。这一切都来源于一个关键字“virtual”。

#include

using namespace std;

class Shape
{
public:
Shape(int x, int y)
:_x(x), _y(y){}

// 父类提供虚函数接口
virtual void draw()
{
cout << “draw Shap “;
cout << “start (“ << _x << “,” << _y << “)” << endl;
}

protected:
int _x;
int _y;
};

// 继承 Shape 类
class Circle : public Shape
{
public:
Circle(int x, int y, int r)
:Shape(x, y), _r(r){}

// 覆写父类 virtual 接口函数
void draw()
{
cout << “draw Circle “;
cout << “start (“ << _x << “,” << _y << “) “;
cout << “radio r = “ << _r << endl;
}

private:
int _r;
};

int main(int argc, char* argv[])
{
// 实例化一个父类对象
Shape s(3, 5);
s.draw();

// 实例化一个子类对象
Circle c(1, 2, 4);
c.draw();

cout << “————————“ << endl;

// 子类对象给父类变量赋值,普通赋值兼容,会出现数据截断
s = c;
s.draw();

// 子类对象给父类引用赋值,可构成多态
// 引用的内部实现就是包装了一个指针
Shape &rs = c;
rs.draw();

// 子类对象给父类指针赋值,可构成多态
Shape *ps = &c;
ps->draw();

return 0;

}

以上代码运行的结果你会发现,最后两个调用的draw都是子类的方法。 2015-05-24_230308 以上这种情况,被称为多态,当然你可能现在感觉不到它存在的意义,在以后的小案例中,你会不断的看到这种情况的出现。没有多态,C++可能没有那么出色。正是类和多态,给 C++ 带来了无数神秘的色彩。最后我们总结一下,多态形成的三个条件:

  1. 是父类中有虚函数。
  2. 子类 override(覆写)父类中的虚函数。
  3. 通过己被子类对象赋值的父类指针,调用共用接口。