Pharo的双重派遣

ruh*_*uhi 7 smalltalk double-dispatch pharo

有人可以用Smalltalk解释Pharo 4.0中双重调度的过程吗?我是Smalltalk的新手并且很难掌握这个概念,因为与Smalltalk相比,它在Java中的实现方式非常不同.如果有人可以通过一个例子解释它,将会非常有帮助.

Uko*_*Uko 13

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

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

现在在Integer课堂上你定义+为:

+ otherObject

   otherObject addInteger: self
Run Code Online (Sandbox Code Playgroud)

Float你定义它像:

+ otherObject

   otherObject addFloat: self
Run Code Online (Sandbox Code Playgroud)

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

另一种策略是使用#adaptTo:andSend:方法.例如,+Point类中定义为:

+ arg 

   arg isPoint ifTrue: [^ (x + arg x) @ (y + arg y)].
   ^ arg adaptToPoint: self andSend: #+
Run Code Online (Sandbox Code Playgroud)

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

Collection 实现这样的方法:

adaptToPoint: rcvr andSend: selector

   ^ self collect: [:element | rcvr perform: selector with: element]
Run Code Online (Sandbox Code Playgroud)

Number实现它:

adaptToPoint: rcvr andSend: selector

   ^ rcvr perform: selector with: self@self
Run Code Online (Sandbox Code Playgroud)

注意,为避免显式类型检查,我们可以通过Point这种方式在自身中定义该方法:

adaptToPoint: rcvr andSend: selector

   ^ (x perform: selector with: arg x) @ (y perform: selector with: arg y)
Run Code Online (Sandbox Code Playgroud)

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