Generic Functions and Methods

Methods belong to generic functions, not to classes. Any code can add methods for any class, so behavior is open for extension without modifying the class definition.

;; A generic function declares an operation; methods implement it for specific classes
(defgeneric greet (entity &optional greeting)
  (:documentation "Return a greeting for ENTITY."))

(defmethod greet ((p person) &optional (greeting "Hello"))
  (format nil "~a, ~a!" greeting (person-name p)))

(defmethod greet ((s string) &optional (greeting "Hi"))   ; methods on built-in classes too
  (format nil "~a, ~a!" greeting s))

(defmethod greet ((n integer) &optional greeting)
  (declare (ignore greeting))
  (format nil "Hello, number ~d" n))

(greet *ana*)                          ; "Hello, Ana B.!"
(greet "Bo" "Hey")                     ; "Hey, Bo!"
(greet 42)                             ; "Hello, number 42"

;; EQL specializers: dispatch on a specific object
(defmethod greet ((x (eql :admin)) &optional greeting)
  (declare (ignore greeting))
  "Welcome back, administrator.")
(greet :admin)

;; Default method on T (the root of all classes)
(defmethod greet ((x t) &optional greeting)
  (declare (ignore greeting))
  "Hello, whatever you are.")

(compute-applicable-methods #'greet (list *ana*))
(remove-method #'greet (find-method #'greet '() (list (find-class 'integer))))