Object Orientation

In most OOP systems, methods belong to classes. In Common Lisp, methods are instances of generic functions, which can dispatch on not just the first argument, but every argument. This makes functions, rather than classes, the prime mover.

Generic Functions and Methods

We define a generic function with defgeneric:

(defgeneric description (object)
  (:documentation "Return a description of an object."))

And we define methods of that function with defmethod:

(defmethod description ((object integer))
  (format nil "The integer ~D" object))

(defmethod description ((object float))
  (format nil "The float ~3,3f" object))

We can try them in the REPL:

CL-USER> (description 10)
"The integer 10"

CL-USER> (description 3.14)
"The float 3.140"

Classes

(defclass vehicle ()
  ((speed :accessor vehicle-speed
          :initarg :speed
          :type real
	      :documentation "The vehicle's current speed."))
  (:documentation "The base class of vehicles."))

When the superclass list is empty, the default base class, standard-class, is used. You can change this, but that’s an advanced topic.

(defclass bicycle (vehicle)
  ((mass :reader bicycle-mass
         :initarg :mass
         :type real
         :documentation "The bike's mass."))
  (:documentation "A bicycle."))

(defclass canoe (vehicle)
  ((rowers :reader canoe-rowers
           :initarg :rowers
           :initform 0
           :type (integer 0)
           :documentation "The number of rowers."))
  (:documentation "A canoe."))

Instantiate:

CL-USER> (defparameter canoe (make-instance 'canoe
                                            :speed 10
                                            :rowers 6))
CANOE

CL-USER> (class-of canoe)
#<STANDARD-CLASS COMMON-LISP-USER::CANOE>

CL-USER> (canoe-rowers canoe)
6

CL-USER> (vehicle-speed canoe)
10

We can get information about a class using describe:

CL-USER> (describe 'canoe)
COMMON-LISP-USER::CANOE
  [symbol]

CANOE names the standard-class #<STANDARD-CLASS
                                 COMMON-LISP-USER::CANOE>:
  Documentation:
    A canoe.
  Direct superclasses: VEHICLE
  No subclasses.
  Not yet finalized.
  Direct slots:
    ROWERS
      Type: (INTEGER 0)
      Initargs: :ROWERS
      Initform: 0
      Readers: CANOE-ROWERS
      Documentation:
       The number of rowers.