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 description (object) (:documentation "Return a description of an object."))
And we define methods of that function with
(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"
(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,
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."))
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
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.