Pharo 中的双重调度

Double dispatch in Pharo

谁能解释一下 Pharo 4.0 中使用 Smalltalk 进行双重调度的过程?我是 Smalltalk 的新手,很难理解这个概念,因为与 Smalltalk 相比,它在 Java 中的实现方式非常不同。如果有人可以用一个例子来解释它,那将非常有帮助。

基本上这个想法是你有方法:

  • #addInteger: 知道如何加整数,
  • #addFloat: 知道如何添加浮点数,
  • 等等……

现在在 Integer class 中,您将 + 定义为:

+ otherObject

   otherObject addInteger: self

Float 中,您将其定义为:

+ otherObject

   otherObject addFloat: self

这样你只需要发送+到一个对象,然后它会要求接收者用所需的方法添加它。

另一种策略是使用#adaptTo:andSend: 方法。例如Point中的+class定义为:

+ arg 

   arg isPoint ifTrue: [^ (x + arg x) @ (y + arg y)].
   ^ arg adaptToPoint: self andSend: #+

首先检查参数是否为 Point,如果不是,则要求参数适应 Point 并发送一些符号(操作),这样可以节省一些重复的方法,这些方法必须执行稍微不同的操作.

Collection 实现方法如下:

adaptToPoint: rcvr andSend: selector

   ^ self collect: [:element | rcvr perform: selector with: element]

Number 是这样实现的:

adaptToPoint: rcvr andSend: selector

   ^ rcvr perform: selector with: self@self

注意,为了避免显式类型检查,我们可以这样在 Point 本身中定义该方法:

adaptToPoint: rcvr andSend: selector

   ^ (x perform: selector with: arg x) @ (y perform: selector with: arg y)

您可以在本演示文稿中看到更多示例:http://www.slideshare.net/SmalltalkWorld/stoop-302double-dispatch