区分接口继承和实现继承
本篇主要讨论pure virtual函数(纯虚函数),impure virtual函数(虚函数),以及non-virtual函数(非虚函数)继承中的实际意义.
概念上通过public继承,实际上可以分为函数接口继承(function interfaces)和函数实现继承(funcion implementations).
考虑下面这个例子
class Shape{
public:
virtual void draw()const = 0;//pure virtual
virtual void error(const std::string& msg);//virtual
int objectID()const;//non-virtual
...
};
class Rectangle:public Shape{
...};
class Ellipse:public Shape{
...};
首先来看pure virtual函数:
Shape定义了一个纯虚函数,所以它是一个抽象类,客户不能创建抽象类的实体,只能创建其派生类(derived classes)的实体.
成员函数的接口总会被继承,Shape的派生类都必须在其内部对这个接口(draw)进行实现.(属于指定接口继承)
这里语法上是可以对Shape的pure virtual函数进行定义的,虽然基类无法创建对象使用,但派生类作用域包含基类,可以通过基类显示利用作用域运算符(::)调用其基类部分使用(看似鸡肋但部分情况下有用,后面详述)。
接下来看impure virtual函数,根据语法,任何派生类继承基类的虚函数,无论是否给与virtual关键字显示指出,其都将拥有虚属性.这里的实际意义在于.你可以自己覆写(override)一个error函数版本,也可以不覆写,默认使用基类提供的缺省版本.(属于指定接口继承&缺省实现继承)
以下面的例子解释一下:
class Airport{