Welcome 微信登录

首页 / 网页编程 / ASP.NET / 闲说继承

闲说继承2009-12-31 博客园 Shuhari继承已经是一个古老的话题了,不过最近又在一些地方看到有人讨论它,加上自己也有一些想法,因 此形成了这篇文章。

继承好不好?

经典的OO理论说:继承是面向对象的三大基石之一。

现代的OO理论说:组合优于继承。

这两种说法显然是彼此冲突的。如果组合优于继承的 话,那么为什么组合没有取代继承成为OO的基石呢?哪一种说法更有道理?

对这个问题,简单的 说哪个比哪个更好其实是没有多大意义的。我们应当从技术发展的历史角度去看,这两种说法各自是在 什么时期产生的,它们形成的背景是什么,才能对此问题有一个更加深刻的理解。

面向对象的思 想形成与上个世纪70年代,但真正在软件开发阵营中流行开则是在80年代末和90年代初的时间。巧合的 是,这一时间也正是以Windows 3.x为代表的图形操作系统兴起的时代。于是面向对象当时所面临的主要 问题就是:如何以OO的理论封装图形界面的开发?很多重要的早期OO思想都是在这个时期形成的,包括 对于继承的使用。

让我们考虑一下图形界面的特点。很容易发现:这个领域确实非常适合使用继 承,因为图形对象天生就存在着is-a关系。比如,所有图像对象都是Window,所有对话框都是Dialog, 所有按钮都是Button,等等。所以我们可以看到的结果就是:所有的图形界面框架都大量使用了继承, 而且继承的层次通常都非常深。例如,下图是WPF中最主要的界面类——Window的继承关系, 它的继承层次深达9层!

所 有图形框架在继承方面几乎无一例外。Java Swing对图形框架由于较多使用MVC,因此继承的深度要浅一 些,但是主要的JFrame类继承深度也达到了6层:

至此我们应该理解,为什么早期OO理论要将继承作为面向对象的基石了。因为当时软件开发的领域还比 较狭窄,所以很多开发者根据自己在图形领域的开发经验认定:继承是OO必不可少的重要基础,并且应 当尽可能的使用。

随着历史的发展,软件开发逐渐进入了两层和三层时代。程序员发现,原来在 桌面应用中得心应手的继承突然之间不那么好用了。为什么呢?

原因之一:两层和三层开发的主 要工作之一是对实体建模。而现实中的实体大多数是相对独立的,它们之间的关系更多的表现为实体之 间的关联,而不是从属关系;

原因之二,很重要的现实问题:多层开发的主要物质基础之一 ——关系数据库,无法很自然的描述继承关系。事实上这也是ORM出现的重要理由之一。但即 使是现在最好的ORM工具,要在数据库中描述继承关系仍然非常复杂。这迫使程序员在相当程度上放弃了 继承;

原因之三:分层的开发方式逐渐流行开来,而继承造成的类属关系耦合非常不利于分层。

出于这些考虑,现代的OO理论为什么更加推荐组合而非继承,应该就容易理解了。

那么 现代OO理论是不是对于继承的看法就完美了呢?我认为也不是。事实上我认为,现代OO理论存在着忽视 继承的问题,很多理论书籍只是简单的告诉我们优先使用组合,而根本就不告诉我们在什么时候应当合 理使用继承,什么时候不应当使用。这是从早期OO的过度使用继承跳到了另一个极端,也是不可取的。