亚里士多德或许是认真研究“类型”概念的第一人,他曾谈及“鱼类和鸟类”的问题。在世界首例面向对象语言Simula-67中,第一次用到了这样的一个概念:
所有对象——尽管各有特色——都属于某一系列对象的一部分,这些对象具有通用的特征和行为。在Simula-67中,首次用到了class
这个关键字,它为程序引入了一个全新的类型(class
和type
通常可互换使用;注释③)。
③:有些人进行了进一步的区分,他们强调“类型”决定了接口,而“类”是那个接口的一种特殊实现方式。
Simula是一个很好的例子。正如这个名字所暗示的,它的作用是“模拟”(Simulate)象“银行出纳员”这样的经典问题。在这个例子里,我们有一系列出纳员、客户、帐号以及交易等。每类成员(元素)都具有一些通用的特征:每个帐号都有一定的余额;每名出纳都能接收客户的存款;等等。与此同时,每个成员都有自己的状态;每个帐号都有不同的余额;每名出纳都有一个名字。所以在计算机程序中,能用独一无二的实体分别表示出纳员、客户、帐号以及交易。这个实体便是“对象”,而且每个对象都隶属一个特定的“类”,那个类具有自己的通用特征与行为。
因此,在面向对象的程序设计中,尽管我们真正要做的是新建各种各样的数据“类型”(Type
),但几乎所有面向对象的程序设计语言都采用了class
关键字。当您看到type
这个字的时候,请同时想到class
;反之亦然。
建好一个类后,可根据情况生成许多对象。随后,可将那些对象作为要解决问题中存在的元素进行处理。事实上,当我们进行面向对象的程序设计时,面临的最大一项挑战性就是:如何在“问题空间”(问题实际存在的地方)的元素与“方案空间”(对实际问题进行建模的地方,如计算机)的元素之间建立理想的“一对一”对应或映射关系。
如何利用对象完成真正有用的工作呢?必须有一种办法能向对象发出请求,令其做一些实际的事情,比如完成一次交易、在屏幕上画一些东西或者打开一个开关等等。每个对象仅能接受特定的请求。我们向对象发出的请求是通过它的“接口”(Interface
)定义的,对象的“类型”或“类”则规定了它的接口形式。“类型”与“接口”的等价或对应关系是面向对象程序设计的基础。
下面让我们以电灯泡为例:
Light lt = new Light();
lt.on();
在这个例子中,类型/类的名称是Light
,可向Light
对象发出的请求包括包括打开(on
)、关闭(off
)、变得更明亮(brighten
)或者变得更暗淡(dim
)。通过简单地声明一个名字(lt
),我们为Light
对象创建了一个“引用”。然后用new
关键字新建类型为Light
的一个对象。再用等号将其赋给引用。为了向对象发送一条消息,我们列出引用名(lt
),再用一个句点符号(.
)把它同消息名称(on
)连接起来。从中可以看出,使用一些预先定义好的类时,我们在程序里采用的代码是非常简单和直观的。