跳至内容

学习 Clojure/多方法和多态性

来自 Wikibooks,开放世界中的开放书籍

多方法和多态性

[编辑 | 编辑源代码]

大多数语言将封装和实现继承视为面向对象编程的主要特征,但 Clojure 认为这些东西被高估了。Clojure 说,面向对象的真正优点是多态性——封装和继承只是限制多态性潜力的束缚。

在 Clojure 中进行面向对象编程时,我们只需使用 structmaps 来代替对象,而使用 Clojure 所谓的多方法来代替传统的封装方法,这些函数根据参数的一些标准(例如参数的数量和/或类型)将参数传递给其他函数。

多方法由三部分组成:一个调度函数、一组方法和与这些方法相关联的一组值。调用多方法会调用调度函数,返回的值决定调用哪个方法。多方法使用clojure/defmulti创建,并通过宏clojure/defmethod向其添加方法。这是一个简化的多方法示例,它只有两个方法

(defmulti victor (fn [a] a))
(defmethod victor 3 [a] "hello")   ; attach a method to call when the dispatch returns 3; the function takes 1 argument, 
                                   ; which it ignores, returning "hello"
(defmethod victor 5 [a] "goodbye")
(victor 3)                         ; returns "hello"
(victor 5)                         ; returns "goodbye"
(victor 4)                         ; exception: No method for dispatch value: 4

请注意,方法的元数必须与多方法的元数匹配,因为调度函数通过传递其参数来调用方法。(还要注意风格上的不一致:defmulti 期待一个函数参数,而defmethod 模仿defn 形式。)

多方法可用于模拟传统的单一和多重继承多态性,以及更灵活的多态性类型。

华夏公益教科书