第1章 对象导言
计算机革命起源于一台机器。因此,程序设计语言的起源看上去也起源于那台机器。
然而,计算机并不仅仅是一台机器,因为它们就像是智力放大工具(Steve Jobs[1]喜欢称其为“智力的自行车”)和另一种富于表现力的媒体。所以,它们渐渐地不太像机器,而更像我们大脑的一部分了,它们还挺像其他的一些富于表现力的媒体(例如写作、绘画、雕刻、动画或电影制作)。面向对象程序设计是“使计算机成为一种富于表现力的媒体”这一华彩乐章的一部分。
本章将介绍面向对象程序设计(OOP)的基本概念,包括OOP开发方法的概述。在读者阅读本书之前,我们假设读者已经有了使用过程型程序设计语言的经验,当然不一定是C语言。
本章是一些背景和辅助材料。如果在未了解这些大背景之前就进入面向对象程序设计,许多人都会感到有困难。因此,这里为读者预先介绍有关OOP的一些基本概念。但是,还有另一些读者,在不见到某些具体结构之前,就不能理解语言的整体概念;这些人不接触某些代码就会停止不前和不知所措。如果读者属于后者,急于学习这门语言的具体内容,则可以跳过本章,这样不会妨碍写程序和学习这门语言。但是,读者以后终将回过头来补充本章的知识,这样才能理解为什么对象如此重要,以及如何用对象设计程序。
1.1 抽象的过程
所有的程序设计语言都提供抽象。可以说,人们能解决的问题的复杂性直接与抽象的类型和质量有关。这里“类型”指的是“要抽象的东西”。汇编语言是对底层机器的小幅度抽象。其后的许多所谓“命令式”语言(例如Fortran、BASIC和C)都是对汇编语言的抽象。这些语言较之汇编语言有了很大的改进,但是它们的主要抽象仍然要求程序员按计算机的结构去思考,而不是按要解决的问题的结构去思考。程序员必须在机器模型(在“解空间”,即建模该问题的空间中,例如在计算机中)和实际上要解决的问题的模型(在“问题空间”,即问题存在的空间中)之间建立联系。程序员必须努力进行这之间的对应,这实际上是程序设计语言之外的任务,它使得程序难以编写且维护费用昂贵,并且作为一种副效应,造就了整个“程序设计方法”产业。
取代对机器建模的另一种方式是对要解决的问题进行建模。像LISP和APL这样的早期语言选取了特殊的“世界观”(“所有的问题最终都是表”或“所有的问题都是算法”),PROLOG则把所有的问题都看做决策链。还有一些语言,创造它们的目的是为了基于约束的编程和专门用于通过绘图符号来编程(后者已被证明局限太大)。这些方法中的每一种对于它所针对的特定问题都是很好的解决方案,但对于这个领域之外的问题,就笨拙难用了。
面向对象的方法为程序员提供了在问题空间中表示各种事物元素的工具,从而向前迈进了一大步。这种表示方法是通用的,并不限定程序员只处理特定类型的问题。我们把问题空间中的事物和它们在解空间中的表示称为“对象”(当然,还需要另外一些对象,它们在问题空间中没有对应物)。其思想是允许程序通过添加新的对象类型,而使程序本身能够根据问题的实际情况进行调整,这样当我们读描述解决方案的代码时,也就是在读表达该问题的文字。这是比以前更灵活和更强大的语言抽象。因此,OOP允许程序员用问题本身的术语来描述问题,而不是用要运行解决方案的计算机的术语来描述问题。当然这些问题的术语仍然与计算机有联系。每个对象看上去像一台小计算机,它有状态,有可以执行的运算。这似乎是现实世界中对象的很好类比,它们都有特性和行为。
一些语言的设计者认为,面向对象程序设计本身并不足以轻易解决所有程序设计问题,他们提倡结合各种方法,形成多范型(multiparadigm)的程序设计语言。[2]
Alan Kay总结了Smalltalk的五个基本特性,这些特性代表了纯面向对象程序设计的方法。Smalltalk是第一个成功的面向对象语言,是C++的基础语言之一。
(1)万物皆对象。对象可以被认为是一个奇特的变量,它能存放数据,而且可以对它“提出请求”,要求它执行对它自身的运算。理论上,我们可以在需要解决的问题中取出任意概念性的成分(狗、建筑物、服务等),把它表示为程序中的对象。
(2)程序就是一组对象,对象之间通过发送消息互相通知做什么。更具体地讲,可以将消息看做是对于调用某个特定对象所属函数的请求。
(3)每一个对象都有它自己的由其他对象构成的存储区。这样,就可以通过包含已经存在的对象创造新对象。因此,程序员可以构造出复杂的程序,而且能将程序的复杂性隐藏在对象的简明性背后。
(4)每个对象都有一个类型。采用OOP术语,每个对象都是某个类的实例(instance),其中“类”(class)与“类型”(type)是同义词。类的最重要的突出特征是“能向它发送什么消息”。
(5)一个特定类型的所有对象都能接收相同的消息。正如后面将看到的,这种特性具有丰富的含义。因为一个“circle”类型的对象也是一个“shape”类型的对象,所以保证circle能接收shape消息。这意味着,我们可以编写与shape通信的代码,该代码能自动地对符合shape描述的任何东西进行处理。这种替换能力(substitutability)是OOP的最强大的思想之一。
[1]史蒂夫・乔布斯(Steve Jobs)是苹果公司的创始人和精神领袖。—编辑注
[2]参见Timothy Budd所写的专著《Multiparadigm Programming in Leda》(Addison-Wesley,1995)。