Java是否支持根据Lisp等多个对象的类型调度特定实现?

Mat*_*der 7 lisp java class multiple-dispatch clos

现在在本页(http://landoflisp.com)上阅读Lisp,我在页面上的第二个段落中找到了以下语句,单击链接CLOS GUILD时显示:

关于该示例的重要注意事项是,为了确定在给定情况下调用哪种混合方法,CLOS需要考虑传递给该方法的两个对象.它基于多个对象的类型调度到该方法的特定实现.这是传统的面向对象语言(如Java或C++)中不可用的功能.

这是示例Lisp代码:

(defclass color () ())
(defclass red (color) ())
(defclass blue (color) ())
(defclass yellow (color) ())

(defmethod mix ((c1 color) (c2 color))
    "I don't know what color that makes")

(defmethod mix ((c1 blue) (c2 yellow))
    "you made green!")

(defmethod mix ((c1 yellow) (c2 red))
    "you made orange!")
Run Code Online (Sandbox Code Playgroud)

不,我认为最后一句话是错的.我实际上可以使用以下Java代码完成此操作:

public class Main {
    public static void main(String[] args) {
        mix(new Red(), new Blue());
        mix(new Yellow(), new Red());
    }

    public static void mix(Color c1, Color c2) {
        System.out.println("I don't know what color that makes");
    }
    public static void mix(Blue c1, Yellow c2) {
        System.out.println("you made green!");
    }
    public static void mix(Yellow c1, Red c2) {
        System.out.println("you made orange!");
    }
}

class Color {}
class Red extends Color {}
class Blue extends Color {}
class Yellow extends Color {}
Run Code Online (Sandbox Code Playgroud)

当我运行它时,它给了我相同的输出:

I don't know what color that makes
you made orange!
Run Code Online (Sandbox Code Playgroud)

所以我的问题是:该页面上的这句话实际上是错误的,并且在Java/C++中是可能的吗?如果是这样,也许在旧版本的Java中不可能?(虽然我非常怀疑,因为这本书只有5年了)如果不是这样的话,在我的例子中我忘记了什么?

Nat*_*hes 9

如果您将示例更改为:

public static void main(String[] args) {
    Color red = new Red();
    Color blue = new Blue();
    Color yellow = new Yellow();
    mix(red, blue);
    mix(yellow, red);
}
Run Code Online (Sandbox Code Playgroud)

那你会得到的

I don't know what color that makes
I don't know what color that makes
Run Code Online (Sandbox Code Playgroud)

Java正在使用编译时类型来确定要调用的方法的重载,其中Lisp在运行时类型上进行调度.Java必须使用Visitor模式才能进行双重调度(根据调用该方法的对象类型和传入的参数类型调用不同的实现).