Hier ist ein allzu einfaches Beispiel zur Veranschaulichung:Clojure ermöglicht die Kapselung und Vererbung, aber kann ich sie kombinieren?
ich eine Implementierung Detail, wie unter Verwendung eines Atom für einen Zähler einkapseln kann:
(defn make-counter
([] (make-counter 0))
([init-val]
(let [c (atom init-val)]
{:get (fn [] @c)
:++ (fn [] (swap! c inc))})))
Aber das bedeutet, dass ich alles neu zu definieren brauchen eine Funktion hinzuzufügen (keine Vererbung):
(defn make-bi-counter
([] (make-bi-counter 0))
([init-val]
(let [c (atom init-val)]
{:get (fn [] @c)
:++ (fn [] (swap! c inc))
:-- (fn [] (swap! c dec))})))
Während, wenn es möglich wäre, zu verlängern nur die eine Funktion:
(assoc c :-- (env (:++ c) (fn [] (swap! c dec))))
(def c (make-counter))
(def b (make-bi-counter))
user=> ((:-- b))
-1
user=> ((:-- b))
-2
user=> ((:get b))
-2
Oder ich nur das Atom ausgesetzt haben könnte und unabhängige Funktionen hatte:
(defn -- [a] (swap! a dec))
(def a (atom 0))
(-- a)
Es scheint die beste Option ist Verkapselung zu verzichten, wenn ‚Vererbung‘ (oder vielleicht genauer: Erweiterung) wünschenswert ist.
Ich glaube, Verkapselung bedeutet nicht, Dinge vor sich selbst zu verbergen. Es geht darum, dein Design zuallererst mit anderen zu teilen. – Alexey