gnu smalltalk 教程-类结构

当你在Smalltalk里编程时,有时需要创建自己的类和消息,以及定义消息对类的处理。在下一章我们将创建一些类,但首先我需要理解Smalltalk类的管理机制。因为本章是纯概念的一章,没有任何代码,所以尽可能的保证简洁和直入主题。

类Object:所有类的父类

 

Smalltalk用树层次结构管理所有的类,在树的最顶层是类Object。在其下有很多特殊的类,比如我们用过的strings,arrays等等。他们以相似的方式聚集在一起。比如,能比较大小的对象全部继承自Magnitude类。(types of objects which may be compared as greater or less than each other fall under a class known as Magnitude.)

当创建一个新的对象时首要任务是找出对象的层次结构。 找出这个问题的答案就如同像艺术一样的科学,并没有一个固定的规则。 我们将见到三种对象,通过这些来让你感受如何管理这些事情。

Animals: 一个学习OOP的经典!

 

想想我们有三种对象,分别代表动物的Animals,鹦鹉的Parrots和猪的Pigs。我们的消息是代表吃的eat,鸣叫的sing和哼哼的snort。首先,我门先插入这些对象到Smalltalk的层次中,看起来就像是这样:

Object
Animals
Parrots
Pigs
这个的意思是Animals, Parrots和Pigs都是Object的子对象,同时不属于任何其他对象.

现在我们必须定义每种动物如何响应不同的消息。

Animals
eat --> Say ``I have now eaten''
sing --> Error
snort --> Error
Parrots
eat --> Say ``I have now eaten''
sing --> Say ``Tweet''
snort --> Error
Pigs
eat --> Say ``I have now eaten"''
sing --> Error
snort --> Say ``Oink''
留意一下我们如何为了保证eat的行为而不得不声明。一个老练的对象设计值会马上意识到这一点,并作为我们没有建立真确分层的线索。让我们试着换一种组织方式:

Object
Animals
Parrots
Pigs
在这里,Parrots继承自Animals,Pigs继承自Parrots. 现在Parrots继承了Animals的所有属性,Pigs继承了Parrots和Animals. 因为这里的继承关系,我们可以重新定义一系列与之对应的动作,来消除之前例子的冗余:
Animals
eat --> Say ``I have now eaten''
sing --> Error
snort --> Error
Parrots
sing --> Say ``Tweet''
Pigs
snort --> Say ``Oink''
应为Parrots和Pigs都继承自Animals,我们仅需定义eat的行为一次。然而,我们却在类的设置上犯了一个错误,当我们尝试Pig sing的时候会发生什么?会是says “Tweet”, 应为文明把Pigs定义成了Parrots的继承者. 让我们试试终级组织方式:

Object
Animals
Parrots
Pigs
现在Parrots和Pigs继承自Animals,而非其他. 现在定义最终的一套行为:

Animals
eat --> Say ``I have eaten''
Parrots
sing --> Say ``Tweet''
Pigs
snort --> Say ``Oink''
这里的改变仅仅省去了不合适的消息。加入Smalltalk发现消息没有被对象以及其父对象声明,Smalltalk会自动返回错误,所以我们没必要手动处理这一系列事情。现在给Pig发送sing消息在不会say “Tweet” 而是以Smalltalk的错误替代

目的: 类层次结语

 

类分层的目的是允许你通过关系组织对象,你可以从父类继承代码到子类。一旦你证实了一种有效的组织类型,你将会发现特殊的技术仅仅需要被构建一次,之后仅需要被子类继承。这保证了你的代码的简单,同时允许你在一个有特殊代码的地方修复错误--其他代码继承相应的修复。

你会发现当你决定添加一个对象的同时,你的经验也在增长。当你变的越来越熟悉存在的一套对象和消息的时候,你的选择也会越来越“适应”已经存在东西。即便如此Smalltalk赞成停在这种情况下来仔细想一样,所以,当你的首次选择似乎很苦难或有错误的倾向时,不要怕