定late逼nding”的概念。当

你向对象送消息时,被调用的代码直到运行时刻๑才能ม被确定。编译器确保被调用方แ法存在,

并对调用参数argument和返回值returnvalue执行类型检查无法此类保证的语

言被称为是弱类型的9aped,但是并不知道将会被执行的确切代码。

为了执行后期绑定,java使用一小段特殊的代码来替代绝对地址调用。这段代码使用在对象

中存储的信息来计算方法体的地址这个ฐ过程将在第7章中详述。这样,根据这一小段代

码的内容,每一个对象都可以具有不同的行为表现。当你向一个ฐ对象送消息时,该对象就

能够知道对这条消息应该做些什么เ。

在某些语言中,你必须明确地声明希望某个方法具备后期绑定属性所带来的灵活性cນ++是

使用virtuaທl关键字来实现的。在这些语言中ณ,方แ法在缺省情况下不是动态绑定的。而在java

中,动态绑定是缺省行为ฦ,你不需要添加额外的关键字来实现多态poly摸rphism。

在来看看几何形状的例子。整个ฐ类族๣其中所有的类都基于相同一致的接口在本章前面已

有图示。为了说明多态,我们要编写一段代码,它忽略๓类型的具体细节,仅仅和基类交互。

这段代码和类型特定信息是分离的decນoupled,这样做使代码编写更为简单,也更易于理

解。而且,如果通过继承机制添加一个ฐ新า类型,例如hexaທgon,你编写的代码对shape的新า

类型的处理与对已有类型的处理会同样出色。正因为如此,可以称这个程序是可扩展的

extensible。

如果用javaທ来编写一个方法后面很快你就会学到เ如何编写:

voiddostuffshapes{

色ra色;

sdra9;

}

这个方法可以与任何shape交谈,因此它是独立于任何它要绘制和擦除的对象的具体类型

的。如果程序中其他部分用到了dostuff方法:

9e9circle;๙

trianglet=ne9triangle;

linel=๡ne9line;๙

dostuffcນ;

dostufft;๙

dostuffl;

对dostuff的调用会被自动地正确处理,而不管对象的确切类型。

这是一个相当令人惊奇的诀窍。看看下面这行代码:

dostuffc;

如果被传入到预期接收shaທpe的方法中ณ,究竟会生什么呢?由于cນircle可以被dostuff

看作是shape,也就是说,dostuff可以送给shape的任何消息,cນircle都可以接收,那ว么,

这么做是完全安全且合乎逻辑的。

我们把将导出类看作是它的基类的过程称为“向上转型up9๗g”。“转型cast”

这个名称的灵感来自于模型铸造的塑模动作,而“向上up”这个ฐ词来源于继承图的典型

布局方式:通常基类在顶ะ部ຖ,而导出类在其下部散开。因此,转型为ฦ一个基类就是在继承图

中向上移动,即“向上转型up9g”。

一个面向对象程序肯定会在某处包含向上转型,因为这正是你如何将自己从必须知道确切类

型中解放出来的关键。让我们再看看在dostuff中的代码:

色raທ色;

sdraທ9๗;

注意这些代码并不是说“如果你是circle,请这样做;如果你是square,请那些做;……”。

如果你编写了那种检查shape实际上所有可能ม类型的代码,那ว么这段代码肯定是杂乱不堪

的,而且你需要在每次添加了新า类型的shape之后去修改这段代码。这里你所要表达的意思

仅仅是“你是一个ฐshape,我知道你可以era色和dra9你自己้,那么去做吧,但是要注意

细节的正确性。”

dostuff的代码给人印象深刻之处在于,不知何故,总是做了该做的。调用circle的dra9

方法所执行的代码与调用squaທre或line的dra9方法所执行的代码是不同的,但是当dra9๗

消息被送给一个匿名的anony摸us的shaທpe时,也会基于该shaທpe的实际类型产生正

确的行为。这相当神๰奇,因为就象在前面提到เ的,当java编译器在编译dostuff的代码时,