Classes in Lisp
Some of these examples are from Marty Hall's site:
http://www.apl.jhu.edu/~hall/lisp.html and see CLOS
Basic template:
(defclass <class-name> (<list of super classes>)
((<slot name 1> :accessor <accessor procedure 1>
:initform <initial value form 1>
:initarg <arg marking symbol 1>)
. . .
(<slot name n> :accessor <accessor procedure n>
:initform <initial value form n>
:initarg <arg marking symbol n>)
)
)
NOTE: classes use "make-instance" NOT "make-" in order to create
an instance of a class.
Example:
1. (from Marty Hall's site)
Class "submarine" has two "slots" - depth and speed.
This class has no superclasses.
(defclass submarine ()
((depth :accessor submarine-depth :initarg :depth)
(speed :accessor submarine-speed :initarg :speed)))
From this definition, you can initialize each slot with ":depth" and
":speed". You access each slot with "submarine-depth" and "submarine-speed".
> (setf sub1 (make-instance 'submarine :depth 100 :speed 5))
> (submarine-speed sub1) --> 5
> (submarine-depth sub1) --> 100
2. Class "circle1" has no superclasses. The two slots, "center" and
"radius", have no initial accessors, forms, or arguments. Access to
each slot is done using "slot-value".
(defclass circle1 ()
((center) (radius)))
> (setf c1 (make-instance 'circle1)) ;; Note the single quote before the class
#<CIRCLE1 20438A34>
> (slot-value c1 'center) --> error because no value has been specified
> (setf (slot-value c1 'center) '(0 0))
(0 0)
> (slot-value c1 'center) --> (0 0)
3. Class "circle2" has initial values supplied for the two slots.
(defclass circle2 ()
((center :initform '(0 0))
(radius :initform 1)))
> (setf c2 (make-instance circle2))
> (slot-value c2 'radius) --> 1
4. Class "circle3" has initial values supplied as well as accessor functions.
(defclass circle3 ()
((center :initform '(0 0) :accessor center-of)
(radius :initform 1 :accessor radius-of)))
> (setf c3 (make-instance 'circle3))
#<CIRCLE3 #x2029B1C9>
> (slot-value c3 'radius) --> 1
> (radius-of c3) --> 1 ;; Here the accessor is used
5. Two classes are defined, Rectangle and Circle, that have accessors
and inititial argument options. Note that no initial forms (values for
the slots) are pre-defined.
(defclass Rectangle ()
((height :accessor rectangle-height :initarg :height)
(width :accessor rectangle-width :initarg :width)))
(defclass Circle ()
((radius :accessor circle-radius :initarg :radius :initform 10)))
A method for Class circle is defined:
(defmethod area ((c Circle))
(* pi (circle-radius c) (circle-radius c)))
6. Inheritance (from Marty Hall's site)
Submarine class "los-angeles" inherits attributes from the superclass
"submarine".
(defclass submarine ()
((depth :accessor sub-depth :initform 100)
(speed :accessor sub-speed :initform 5)))
(defclass los-angeles (submarine)
((max-speed :accessor losangeles-max :initform 10)))
> (setf sub1 (make-instance 'submarine))
> (setf sub2 (make-instance 'los-angeles))
> (sub-speed sub1) --> 5
> (sub-speed sub2) --> 5
> (losangeles-max sub2) --> 10