java - Java 是否支持像 Lisp 那样基于多个对象的类型分派(dispatch)到特定的实现?

标签 java class lisp clos multiple-dispatch

在当前页面 ( http://landoflisp.com ) 上阅读 Lisp,我在单击链接 CLOS GUILD 时显示的页面倒数第二段中发现了以下语句:

The important thing to note about the example is that in order to figure out which mix method to call in a given situation, the CLOS needs to take into account both of the objects passed into the method. It is dispatching to a specific implementation of the method based on the types of multiple objects. This is a feature that is not available in traditional object-oriented languages, such as Java or 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!")

不,我认为最后一句话是错误的。我实际上可以使用以下 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 {}

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

I don't know what color that makes
you made orange!

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

最佳答案

如果您将示例更改为:

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

然后你会得到

I don't know what color that makes
I don't know what color that makes

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

关于java - Java 是否支持像 Lisp 那样基于多个对象的类型分派(dispatch)到特定的实现?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32308614/

相关文章:

javascript - 事件/异步语言列表

java - 如何以任意顺序给出命令行参数?

Java while循环及其他

Java树节点选择

java - java中如何从父类对象加载子对象

installation - 下载 ARC Lisp Ubuntu 16.04 Xenial

delphi - TObject 和 NIL Delphi 中的析构函数类

python - 尝试调用类方法时出现 NameError 问题

jquery - 高级选择问题

引用 cons 单元格