Ral*_*lph 9 polymorphism clojure
在"Clojure的喜悦"一书中,defprotocol提供了表达式问题的解决方案- "希望为现有的具体类实现一组现有的抽象方法,而不必更改定义任何一个的代码."
给出的例子如下:
(defprotocol Concatenatable
(cat [this other]))
(extend-type String
Concatenatable
(cat [this other]
(.concat this other)))
(cat "House" " of Leaves")
;=> "House of Leaves"
(extend-type java.util.List
Concatenatable
(cat [this other]
(concat this other)))
(cat [1 2 3] [4 5 6])
;=> (1 2 3 4 5 6)
Run Code Online (Sandbox Code Playgroud)
有人认为这在Java这样的语言中是不可能的,但它与以下内容有何不同?
public class Util {
public static String cat(final String first,
final String second) {
return first.concat(second);
}
public static <T> List<T> cat(final List<T> first,
final List<T> second) {
final List<T> list = new List<T>(first);
list.addAll(second);
return list;
}
}
Run Code Online (Sandbox Code Playgroud)
毕竟,两者都是类似的:
(cat "House" " of Leaves")
Util.cat("House", " of Leaves");
Run Code Online (Sandbox Code Playgroud)
Clojure的功能cat是不一个方法上String和List类,而是一个独立的功能被重载以接受任一String或List参数.
虽然我真的很喜欢Clojure,但我不理解这种结构的优越性.
ama*_*loy 21
好的.你cat大张旗鼓地释放这个Java库,每个人都下载它.它太棒了我想让我自己的TVCommercial类型可以连接,这样我就可以将它发送到你的库中可连接对象的位.
但我不能,因为你打电话Util.cat(obj1, obj2),没有超载TVCommercial.我无法扩展您的代码来处理我的类型,因为我没有您的代码.
您可以将Concatenable定义为解决此问题的接口:
interface Concatenable {
Concatenable cat(Concatenable other);
}
Run Code Online (Sandbox Code Playgroud)
但是现在我不能写一个可以连接的类......我不知道,一个AnimalHandler,它处理cats.Clojure的协议通过分散调度功能和实现来解决这两个问题:它们遍布整个地方,而不是在某个单独的位置.在Java中,您可以选择:
Clojure基本上完成了后者,但由于它使用了命名空间名称,因此没有与其他认为cat是一个好函数名称的协议冲突的危险.