Sök…


Skapa en grundläggande CLOS-klass utan föräldrar

En CLOS-klass beskrivs av:

  • ett namn
  • en lista med superklass
  • en lista med slots
  • ytterligare alternativ som dokumentation

Varje kortplats har:

  • ett namn
  • ett initialiseringsformulär (valfritt)
  • ett initialiseringsargument (valfritt)
  • en typ (valfritt)
  • en dokumentationssträng (valfritt)
  • accessor, läsare och / eller författarfunktioner (valfritt)
  • ytterligare alternativ som tilldelning

Exempel:

(defclass person ()
  ((name
    :initform      "Erika Mustermann" 
    :initarg       :name 
    :type          string
    :documentation "the name of a person"
    :accessor      person-name)
   (age
    :initform      25
    :initarg       :age
    :type          number
    :documentation "the age of a person"
    :accessor      person-age))
  (:documentation "a CLOS class for persons with name and age"))

En standardutskriftsmetod:

(defmethod print-object ((p person) stream)
  "The default print-object method for a person"
  (print-unreadable-object (p stream :type t :identity t)
    (with-slots (name age) p
      (format stream "Name: ~a, age: ~a" name age))))

Skapa instanser:

CL-USER > (make-instance 'person)
#<PERSON Name: Erika Mustermann, age: 25 4020169AB3>

CL-USER > (make-instance 'person :name "Max Mustermann" :age 24)
#<PERSON Name: Max Mustermann, age: 24 4020169FEB>

Mixins och gränssnitt

Common Lisp har inte gränssnitt i den meningen att vissa språk (t.ex. Java) gör det, och det finns mindre behov av den typen av gränssnitt eftersom Common Lisp stöder flera arv och generiska funktioner. Dock kan samma typ av mönster realiseras enkelt med mixinklasser. Detta exempel visar specifikationen för ett samlingsgränssnitt med flera motsvarande generiska funktioner.

;; Specification of the COLLECTION "interface"

(defclass collection () ()
  (:documentation "A collection mixin."))

(defgeneric collection-elements (collection)
  (:documentation "Returns a list of the elements in the collection."))

(defgeneric collection-add (collection element)
  (:documentation "Adds an element to the collection."))

(defgeneric collection-remove (collection element)
  (:documentation "Removes the element from the collection, if it is present."))

(defgeneric collection-empty-p (collection)
  (:documentation "Returns whether the collection is empty or not."))

(defmethod collection-empty-p ((c collection))
  "A 'default' implementation of COLLECTION-EMPTY-P that tests
whether the list returned by COLLECTION-ELEMENTS is the empty
list."
  (endp (collection-elements c)))

En implementering av gränssnittet är bara en klass som har mixin som en av dess superklasser och definitioner av lämpliga generiska funktioner. (Vid denna punkt, lägg märke till att mixin-klassen egentligen bara är för att signalera avsikten att klassen implementerar "gränssnittet". Detta exempel skulle fungera lika bra med några generiska funktioner och dokumentation som säger att det finns metoder på funktionen för klassen.)

;; Implementation of a sorted-set class

(defclass sorted-set (collection)
  ((predicate
    :initarg :predicate
    :reader sorted-set-predicate)
   (test
    :initarg :test
    :initform 'eql
    :reader sorted-set-test)
   (elements
    :initform '()
    :accessor sorted-set-elements
    ;; We can "implement" the COLLECTION-ELEMENTS function, that is,
    ;; define a method on COLLECTION-ELEMENTS, simply by making it
    ;; a reader (or accessor) for the slot.
    :reader collection-elements)))

(defmethod collection-add ((ss sorted-set) element)
  (unless (member element (sorted-set-elements ss)
                  :test (sorted-set-test ss))
    (setf (sorted-set-elements ss)
          (merge 'list
                 (list element)
                 (sorted-set-elements ss)
                 (sorted-set-predicate ss)))))

(defmethod collection-remove ((ss sorted-set) element)
  (setf (sorted-set-elements ss)
        (delete element (sorted-set-elements ss))))

Slutligen kan vi se hur en instans av den sorterade klassen ser ut när man använder "gränssnitt" -funktionerna:

(let ((ss (make-instance 'sorted-set :predicate '<)))
  (collection-add ss 3)
  (collection-add ss 4)
  (collection-add ss 5)
  (collection-add ss 3)
  (collection-remove ss 5)
  (collection-elements ss))
;; => (3 4)


Modified text is an extract of the original Stack Overflow Documentation
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow