【发布时间】:2015-06-15 17:56:27
【问题描述】:
有人可以解释一下在 Pharo 4.0 中使用 Smalltalk 进行双重调度的过程吗?我是 Smalltalk 的新手,很难理解这个概念,因为与 Smalltalk 相比,它在 Java 中的实现方式非常不同。如果有人可以用一个例子来解释它,那将非常有帮助。
【问题讨论】:
标签: smalltalk pharo double-dispatch
有人可以解释一下在 Pharo 4.0 中使用 Smalltalk 进行双重调度的过程吗?我是 Smalltalk 的新手,很难理解这个概念,因为与 Smalltalk 相比,它在 Java 中的实现方式非常不同。如果有人可以用一个例子来解释它,那将非常有帮助。
【问题讨论】:
标签: smalltalk pharo double-dispatch
基本上这个想法是你有方法:
#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 并发送一些符号(操作),这样可以节省一些必须执行稍微不同的操作的方法的重复。
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
【讨论】: