【问题标题】:Double dispatch in PharoPharo 的双重调度
【发布时间】:2015-06-15 17:56:27
【问题描述】:

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

【问题讨论】:

    标签: smalltalk pharo double-dispatch


    【解决方案1】:

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

    • #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

    【讨论】:

    • 谢谢,现在说得通了。基本上你调用一个泛型方法,在所有相关的类中定义它。但是在您希望参数实际转到的特定类中,您可以使用特定参数放置一些特定的实现。确定方法调用后,根据对象的选择器和接收器确定调用哪个方法。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多