Учебники

ЛИСП — ЗАКРЫТЬ

Общий 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 и введите в него следующий код.

Live Demo

(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 и введите в него следующий код.

Live Demo

(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 и введите в него следующий код.

Live Demo

(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))

Когда вы выполняете код, он возвращает следующий результат —