跳至內容

學習 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 形式。)

多方法可用於模擬傳統的單一和多重繼承多型性,以及更靈活的多型性型別。

華夏公益教科書