在当前页面 ( 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/