common lisp predated the advance of object-oriented programming by couple of decades. however, it object-orientation was incorporated into it at a later stage.
defining classes
the defclass macro allows creating user-defined classes. it establishes a class as a data type. it has the following syntax −
(defclass class-name (superclass-name*) (slot-description*) class-option*))
the slots are variables that store data, or fields.
a slot-description has the form (slot-name slot-option*), where each option is a keyword followed by a name, expression and other options. most commonly used slot options are −
:accessor function-name
:initform expression
:initarg symbol
for example, let us define a box class, with three slots length, breadth, and height.
(defclass box () (length breadth height) )
providing access and read/write control to a slot
unless the slots have values that can be accessed, read or written to, classes are pretty useless.
you can specify accessors for each slot when you define a class. for example, take our box class −
(defclass box () ((length :accessor length) (breadth :accessor breadth) (height :accessor height) ) )
you can also specify separate accessor names for reading and writing a slot.
(defclass box () ((length :reader get-length :writer set-length) (breadth :reader get-breadth :writer set-breadth) (height :reader get-height :writer set-height) ) )
creating instance of a class
the generic function make-instance creates and returns a new instance of a class.
it has the following syntax −
(make-instance class {initarg value}*)
example
let us create a box class, with three slots, length, breadth and height. we will use three slot accessors to set the values in these fields.
create a new source code file named main.lisp and type the following code in it.
(defclass box () ((length :accessor box-length) (breadth :accessor box-breadth) (height :accessor box-height) ) ) (setf item (make-instance 'box)) (setf (box-length item) 10) (setf (box-breadth item) 10) (setf (box-height item) 5) (format t "length of the box is ~d~%" (box-length item)) (format t "breadth of the box is ~d~%" (box-breadth item)) (format t "height of the box is ~d~%" (box-height item))
when you execute the code, it returns the following result −
length of the box is 10 breadth of the box is 10 height of the box is 5
defining a class method
the defmethod macro allows you to define a method inside the class. the following example extends our box class to include a method named volume.
create a new source code file named main.lisp and type the following code in it.
(defclass box () ((length :accessor box-length) (breadth :accessor box-breadth) (height :accessor box-height) (volume :reader volume) ) ) ; method calculating volume (defmethod volume ((object box)) (* (box-length object) (box-breadth object)(box-height object)) ) ;setting the values (setf item (make-instance 'box)) (setf (box-length item) 10) (setf (box-breadth item) 10) (setf (box-height item) 5) ; displaying values (format t "length of the box is ~d~%" (box-length item)) (format t "breadth of the box is ~d~%" (box-breadth item)) (format t "height of the box is ~d~%" (box-height item)) (format t "volume of the box is ~d~%" (volume item))
when you execute the code, it returns the following result −
length of the box is 10 breadth of the box is 10 height of the box is 5 volume of the box is 500
inheritance
lisp allows you to define an object in terms of another object. this is called inheritance. you can create a derived class by adding features that are new or different. the derived class inherits the functionalities of the parent class.
the following example explains this −
example
create a new source code file named main.lisp and type the following code in it.
(defclass box () ((length :accessor box-length) (breadth :accessor box-breadth) (height :accessor box-height) (volume :reader volume) ) ) ; method calculating volume (defmethod volume ((object box)) (* (box-length object) (box-breadth object)(box-height object)) ) ;wooden-box class inherits the box class (defclass wooden-box (box) ((price :accessor box-price))) ;setting the values (setf item (make-instance 'wooden-box)) (setf (box-length item) 10) (setf (box-breadth item) 10) (setf (box-height item) 5) (setf (box-price item) 1000) ; displaying values (format t "length of the wooden box is ~d~%" (box-length item)) (format t "breadth of the wooden box is ~d~%" (box-breadth item)) (format t "height of the wooden box is ~d~%" (box-height item)) (format t "volume of the wooden box is ~d~%" (volume item)) (format t "price of the wooden box is ~d~%" (box-price item))
when you execute the code, it returns the following result −
length of the wooden box is 10 breadth of the wooden box is 10 height of the wooden box is 5 volume of the wooden box is 500 price of the wooden box is 1000