当前位置:编程学习 > C/C++ >>

谈谈继承的局限性

有一种普遍的说法是把封装、继承和多态并称为面向对象的三大特征。如果你很熟悉C++并且对面向对象思想有过一些思考,那么很可能对这个说法有过怀疑,面向对象思想在本质上认为世界是由对象构成的,和面向过程是世界观的不同,而所谓的三大特征实际和面向对象的思想本质没有半毛钱的关系,准确的表述应该是封装、继承和多态是C++相对于C的三大特征。如果你碰巧了解一点C++编译器可能会发现封装也好,继承、多态也好都只是语法糖,技巧层面的东西而已,和思想无关。

以上为废话。

 

本文主要就C++的继承机制进行一些讨论。很多C++教材在讲到继承时喜欢利用几何上的一些概念,比如对如下的集合关系进行建模:

 

\

         在一次内部技术培训的时候我提出这个问题,结果大家都沉默不语,于是我特意找了个新手程序员回答,他给出了我预料之中的答案:以四边形作为基类,矩形和正方形依次继承下来。没人表示同意也没人表示反对,可能所有的人第一反应得出的都是这个方案,但老鸟程序员会马上察觉出其中的不妥,即使他给不出更好的方案。

         实际上在没有给定需求场景的情况下你永远无法设计出一个类,更不要说设计一组类和这些类的层次关系。很多教材都有这个毛病,上来就设计Student、Teacher而没说要完成的功能是什么,即使是做了许多年C++之后再回过头来看那些例子还是晕忽忽的,何况初学者,——当然这也许仅仅是因为我自己太笨。

         我们设定两个简单的需求取边长和计算面积,暂时不考虑继承关系而分别实现三个类,那么它们是下面这个样子的:

	1 class Quadrangle
2 {
3 public:
4     int GetSideLength(int index);
5     int GetArea(void);
6 
7 private:
8     int m_arrSlide[4];
9 };
10 
11 class Rectangle
12 {
13 public:
14     int GetWidth(void);
15     int GetHeight(void);
16     int GetArea(void);
17 
18 private:
19     int m_nWidth;
20     int m_nHeight;
21 };
22 
23 class Square
24 {
25 public:
26     int GetWidth(void);
27     int GetArea(void);
28 
29 private:
30     int m_nWidth;
31 };

显然,正方形四边形Square 的实现最简单,四边形Quadrangle的实现最复杂(知道四条边长能确定唯一的四边形吗?)。继承机制有一个特点:派生类总是比基类更复杂,因为派生类是在完整的继承了基类实现的基础上增加新的成员、方法。由四边形到矩形再到正方形却是越来越简单,这就形成了一个悖论,导致我们无法按照继承的层次描述三者的关系。

一个老到的程序员会告诉你最好分别实现三个类,不考虑三个者之间的关系,这在大部分场景中是可行的。如果确实需要描述三者之间的层次关系,我能想到的最好的方式是使用接口:

\

 

接口用来描述层次关系,各个类独立实现。由此也可以看出,虽然C++中的接口是用纯虚类继承实现的,但实际上接口机制和继承机制是两种完全不同的东西。

 

到现在为止,我们可以得出结论:继承机制实际上很难描述现实概念的层次关系,这是它的局限性。对继承的应用很多情况下并不是为了描述真实概念的层次关系,而只是组织代码的一种形式。比如可以尝试下用继承关系描述一棵进化树,你会发现这个基本上很难。

 

在C++中引入继承机制的目的是什么,大部分资料对此都语焉不详,但是无论如何至少有一半的目的是为了组织和复用代码,继承扩展是很常用的手法,在MFC、WTL等框架中到处可以看到这样的代码。但是在实际的应用中一定要避免单纯为了复用代码而使用继承机制,典型的案例比如窗口和控件。

窗口和控件是两种完全不同的东西,微软为了复用消息机制把两个概念硬是揉在了一起,所有的控件都从窗口继承下来,这直接导致了GUI框架的高复杂度和难以扩展。

代码复用只是良好设计的副产品而不应该是设计本身的目的。

 

最后总结一下本文的核心观点:

1.       继承机制有很大的局限性,难于描述现实概念的层次关系;

2.       使用继承时避免生搬硬套现实概念的层次关系;

3.       避免单纯以代码复用为目的使用继承

微博:@飞舞的烟灰缸

补充:软件开发 , C语言 ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,