-
-
Save esshka/545cb1f4c9e20e4e8fec to your computer and use it in GitHub Desktop.
Demonstration of implementation "inheritance" in clojure
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; Define a "base type" of Dog | |
(defrecord Dog [breed]) | |
;; Define a "sub type" of TrainedDog | |
(defrecord TrainedDog [dog word]) | |
;; The interface that both Dog and TrainedDog will implement | |
(defprotocol Talker | |
(bark [_]) | |
(speak [_]) | |
(to-dog [_])) | |
;; The base behavior that will be used for Dogs and TrainedDogs | |
(def base-behavior {:bark (fn [doggable] | |
(str "arf (" (:breed (to-dog doggable)) ")")) | |
:speak (fn [doggable] | |
(bark doggable)) | |
:to-dog (fn [dog] dog)}) | |
;; Use the base behavior as the implmentation of the Dog Talker behavior. | |
(extend Dog | |
Talker | |
base-behavior) | |
(def fido (Dog. "collie")) | |
(bark fido) | |
;; => "arf (collie)" | |
(speak fido) | |
;; => "arf (collie)" | |
;; For the TrainedDog, start with the base-behavior but "override" two | |
;; of the functions with alternate behavior. | |
(extend TrainedDog | |
Talker | |
(merge base-behavior | |
{:speak (fn [trained-dog] (str (:word trained-dog))) | |
:to-dog (fn [trained-dog] (:dog trained-dog))})) | |
(def rex (TrainedDog. (Dog. "yorkie") "hello")) | |
;; TrainedDogs use the 'bark' implementation from the base-behavior | |
(bark rex) | |
;; => "arf (yorkie)" | |
;; TrainedDogs use their own 'speak' implementation | |
(speak rex) | |
;; => "hello" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment