Multiple Dispatch & Static Overload.

It is NOT true that all OOP languages require the cumbersome double-dispatch pattern to implement binary operatoins in a full OOP style. Languages with multimethods, also known as multiple dispatch, provide more intuitive solutions.

支持 multiple dispatch 的语言允许在类中声明多个同名方法。举例来说,在允许 multiple dispatch 的语言中,在 Int, MyString, 与 MyRational 类中均可定义三个名为 add_values 的方法;也就是说程序中将会有 3 * 3 = 9 个名为 add_values 的方法,分别对应 9 个 cases。

Each add_values method would indicate the class it expects for its argument. Then e1.eval.addvalues e2.eval would pick the right one of the 9 by, at run-time, considering the class of the result of e1.eval and the class of the result of e2.eval.

Ruby, Java, C#, C++ 等语言采用的均是 dynamic single dispatch: the method-lookup rules involve the run-time class of the receiver (the object whose method we are calling, or self), not the run-time class of the argument(s).

而 dynamic multiple dispatch 不仅仅考虑 receiver 的类,它将根据多个对象 (当然包括传入的参数) 的类来选择需要被调用的方法。因此可以说 multiple dispatch is “even more dynamic dispatch”.

Java 与 C++ 这样的 statically typed languages 不支持 multiple dispatch,但它们允许在类中定义同名方法,并通过我们所声明的实参类型 (types) 来选择调用的方法。这一 semantic 被称为 static overloading

Static Overloading Multiple Dispatch
languages statically typed OOP dynamically typed OOP
argument dependence types of arguments at compile-time run-time class of the result of evaluating the arguments
receiver dependence run-time class of receiver (odd hybrid?) run-time class of receiver
double dispatch does not avoid double dispatch simplify cumbersome double dispatch

在 (dynamic) single dispatch 根据 receiver 的 run-time class 选择调用的方法这一基础上,multiple dispatch 根据参数的 run-time class 进一步选择,static overloading 根据参数的 types 进一步选择。

但 multiple dispatch 能够在某种程度上简化笨重的 double dispatch technique;static overloading 则无法做到这一点,当需要使用 double dispatch 时还是无法避免。