Общий LISP предшествовал продвижению объектно-ориентированного программирования на пару десятилетий. Однако объектная ориентация была включена в него на более позднем этапе.
Определение классов
Макрос defclass позволяет создавать пользовательские классы. Он устанавливает класс как тип данных. Он имеет следующий синтаксис —
(defclass class-name (superclass-name*) (slot-description*) class-option*))
Слоты — это переменные, в которых хранятся данные или поля.
Описание слота имеет форму (slot-name slot-option *), где каждая опция является ключевым словом, за которым следует имя, выражение и другие опции. Наиболее часто используемые варианты слотов —
-
: имя функции доступа
-
: выражение initform
-
: символ initarg
: имя функции доступа
: выражение initform
: символ initarg
Например, давайте определим класс Box с длиной, шириной и высотой трех слотов.
(defclass Box () (length breadth height) )
Предоставление доступа и контроля чтения / записи в слот
Если слоты не имеют значений, к которым можно обращаться, читать или записывать, классы довольно бесполезны.
Вы можете указать аксессоры для каждого слота при определении класса. Например, возьмем наш класс Box —
(defclass Box () ((length :accessor length) (breadth :accessor breadth) (height :accessor height) ) )
Вы также можете указать отдельные имена доступа для чтения и записи слота.
(defclass Box () ((length :reader get-length :writer set-length) (breadth :reader get-breadth :writer set-breadth) (height :reader get-height :writer set-height) ) )
Создание экземпляра класса
Общая функция make-instance создает и возвращает новый экземпляр класса.
Он имеет следующий синтаксис —
(make-instance class {initarg value}*)
пример
Давайте создадим класс Box с тремя слотами: длина, ширина и высота. Мы будем использовать три слота для доступа к значениям в этих полях.
Создайте новый файл исходного кода с именем main.lisp и введите в него следующий код.
(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))
Когда вы выполняете код, он возвращает следующий результат —
Length of the Box is 10 Breadth of the Box is 10 Height of the Box is 5
Определение метода класса
Макрос defmethod позволяет вам определять метод внутри класса. В следующем примере наш класс Box расширяется, чтобы включить метод с именем volume.
Создайте новый файл исходного кода с именем main.lisp и введите в него следующий код.
(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))
Когда вы выполняете код, он возвращает следующий результат —
Length of the Box is 10 Breadth of the Box is 10 Height of the Box is 5 Volume of the Box is 500
наследование
LISP позволяет вам определять объект в терминах другого объекта. Это называется наследством. Вы можете создать производный класс, добавив новые или новые функции. Производный класс наследует функции родительского класса.
Следующий пример объясняет это —
пример
Создайте новый файл исходного кода с именем main.lisp и введите в него следующий код.
(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))
Когда вы выполняете код, он возвращает следующий результат —