LISP - ЗАКРЫТЬ

Common LISP на пару десятилетий предшествовал развитию объектно-ориентированного программирования. Однако на более позднем этапе в нее была включена объектная ориентация.

Определение классов

В defclassмакрос позволяет создавать пользовательские классы. Он устанавливает класс как тип данных. Он имеет следующий синтаксис -

(defclass class-name (superclass-name*)
   (slot-description*)
   class-option*))

Слоты - это переменные, в которых хранятся данные или поля.

Описание слота имеет форму (имя-слота опция-слота *), где каждая опция - это ключевое слово, за которым следует имя, выражение и другие опции. Наиболее часто используемые варианты слотов -

  • :accessor имя-функции

  • :initform выражение

  • :initarg условное обозначение

Например, давайте определим класс Box с тремя ячейками длины, ширины и высоты.

(defclass Box () 
   (length 
   breadth 
   height)
)

Предоставление доступа и управления чтением / записью в слот

Если у слотов нет значений, к которым можно получить доступ, прочитать или записать, классы бесполезны.

Вы можете указать accessorsдля каждого слота при определении класса. Например, возьмите наш класс Box -

(defclass Box ()
   ((length :accessor length)
      (breadth :accessor breadth)
      (height :accessor height)
   )
)

Вы также можете указать отдельные accessor имена для чтения и записи слота.

(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 позволяет вам определять объект в терминах другого объекта. Это называетсяinheritance.Вы можете создать производный класс, добавив новые или другие функции. Производный класс наследует функции родительского класса.

Следующий пример объясняет это -

пример

Создайте новый файл исходного кода с именем 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))

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

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