在法鲁的双重派遣 [英] Double dispatch in Pharo

查看:98
本文介绍了在法鲁的双重派遣的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

解决方案

从本质上讲,您的想法是:

  • #addInteger:知道如何添加整数,
  • #addFloat:知道如何添加浮点数,
  • 依此类推...

现在在Integer类中,将+定义为:

+ otherObject

   otherObject addInteger: self

Float中的定义如下:

+ otherObject

   otherObject addFloat: self

这样,您只需要将+发送到对象,然后它将要求接收者使用所需的方法将其添加.

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

+ arg 

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

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

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

Could someone please explain the process of double dispatch in Pharo 4.0 with Smalltalk? I am new to Smalltalk and am having difficulty grasping the concept, since it is implemented very differently in Java as compared to Smalltalk. It will be very helpful if some one could explain it with an example.

解决方案

Essentially the idea is that you have method:

  • #addInteger: which knows how to add integers,
  • #addFloat: which knows how to add floats,
  • and so on…

Now in Integer class you define + as:

+ otherObject

   otherObject addInteger: self

in Float you define it like:

+ otherObject

   otherObject addFloat: self

This way you only need to send + to an object and then it will ask the receiver to add it with the required method.

Another strategy is to use #adaptTo:andSend: methods. For example + in Point class is defined as:

+ arg 

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

Which first checks if the argument is a Point, and if it's not, asks the argument to adapt to Point and send some symbol (operation), this saves some duplication of the methods that have to perform a slightly different operation.

Collection implements the method like this:

adaptToPoint: rcvr andSend: selector

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

and Number implements it like that:

adaptToPoint: rcvr andSend: selector

   ^ rcvr perform: selector with: self@self

Note, that to avoid explicit type checking, we could define that method in the Point itself this way:

adaptToPoint: rcvr andSend: selector

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

You can see more examples in this presentation: http://www.slideshare.net/SmalltalkWorld/stoop-302double-dispatch

这篇关于在法鲁的双重派遣的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆