Clojure inheritance

So here’s ye old car example. Pretend we have a class Car in (insert your favourite OO language here), then we extend the car class with Sportscar and Pickup, the door-count method of the Car class will return “I have four doors” and the car-description method is overridden in the two extending classes.

I think you get the picture, but how to accomplish the equivalent in Clojure?

Here’s an example using multi methods and derive.

(alias 'car '
(defstruct car-instance :type)

(defmulti car-description :type)
(defmethod car-description ::Car [_] "I'm a random car.")
(defmethod car-description ::Sportscar [_] "I'm a fast sportscar.")
(defmethod car-description ::Pickup [_] "I'm a practical pickup truck.")

(defmulti door-count :type)
(defmethod door-count ::Car [_] "I have four doors.")

(def a-918-spyder (struct car-instance ::Sportscar))
(def a-hilux (struct car-instance ::Pickup))

(derive ::Sportscar ::Car)
(derive ::Pickup ::Car)

(println (door-count a-918-spyder))
(println (door-count a-hilux))

(println (car-description a-hilux))

Note how we derive Sportscar and Pickup after they’ve been defined and it works anyway. The end result is that the calls to car-description will print respective description but the call to door-count will print “I have four doors” for both cars.

There you have it, inheritance in Clojure in a nutshell. You get basically the same code reuse power you get with traditional OO but without the straitjacket.

By now you should be able to figure out how to get the spyder to return “I have two doors”.

Related Posts

Tags: ,