区分接口继承和实现继承
c++的(公有)继承主要有两个意图:实现继承和接口继承。实现继承其实体现了面向对象封装的特性,在不修改原有代码的基础上进行扩展,然而这种继承,目前普遍认为往往带来类结构复杂不便维护的后果,也往往会有更好的办法来代替它,而接口继承为了实现多态特性。
实现继承
通过一般函数的继承实现。
特性:这种继承使一种子类不会有不同行为的继承。子类不能重新定义基类的实现,而只能使用基类的实现。
纯粹的接口继承(pure virtual)
通过纯虚函数实现。基类不提供实现(当然,从语法上提供实现也是可以的,但是经常不会这么做)。
纯虚函数最重要的特性:子类必须重新实现自己的版本。所以,这个特性就决定了派生类必定会覆盖基类中的实现,所以基类中的实现经常是不写的。
接口继承并且有缺省的实现(impure virtual)
通过非纯虚函数实现。这种继承意图是结合了实现继承和结构继承,既可以实现自己版本的接口,也可以使用基类的版本。
重要特性:派生类不强制重新实现自己的版本,但基类必须有实现。这种特性就给用户一种选择,你可以有自己的实现,也可以用基类的实现。这个特性最大的问题在于继承者没有明确表达我要使用默认缺省实现的时候使用了默认缺省的实现,这一点书中航班的例子讲的很清楚,这可能会造成严重的后果,你看实现继承虽然在代码重用上有一定作用,但往往有很危险的隐患。书中推荐的有默认实现的接口继承的方法是,利用纯虚函数的特性,在基类的纯虚函数中给出实现,而让派生类的接口主动调用这个默认实现。
那么……
基类中函数应该被声明为pure virtual ,impure virtual,还是non-virtual???
如果所有函数均是non-virtual则失去了继承的意义,因为实现继承往往是有害的,应该考虑不使用继承是不是也能方便的实现同样的功能。牢记继承最大的作用在于多态的实现。
如果所有函数都是虚函数则是不是缺乏坚定立场的前兆(书中原话)。当然,不是说这种继承不对,如果全部函数都是虚函数,这就相当于Java中的接口类的概念。
网友评论