学习 Clojure/多方法和多态性
外观
大多数语言将封装和实现继承视为面向对象编程的主要特征,但 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 形式。)
多方法可用于模拟传统的单一和多重继承多态性,以及更灵活的多态性类型。