LISP - ZAMKNIJ

Common LISP wyprzedził rozwój programowania obiektowego o kilka dekad. Jednak na późniejszym etapie została do niego włączona orientacja obiektowa.

Definiowanie klas

Plik defclassmakro umożliwia tworzenie klas zdefiniowanych przez użytkownika. Ustanawia klasę jako typ danych. Ma następującą składnię -

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

Szczeliny to zmienne przechowujące dane lub pola.

Opis slotu ma postać (nazwa-slotu opcja-slotu *), gdzie każda opcja jest słowem kluczowym, po którym następuje nazwa, wyrażenie i inne opcje. Najczęściej używane opcje slotów to -

  • :accessor nazwa-funkcji

  • :initform wyrażenie

  • :initarg symbol

Na przykład zdefiniujmy klasę Box z trzema długościami, szerokości i wysokości szczelin.

(defclass Box () 
   (length 
   breadth 
   height)
)

Zapewnienie kontroli dostępu i odczytu / zapisu do gniazda

O ile gniazda nie mają wartości, do których można uzyskać dostęp, odczytać lub zapisać, klasy są dość bezużyteczne.

Możesz określić accessorsdla każdego gniazda podczas definiowania klasy. Weźmy na przykład naszą klasę Box -

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

Możesz również określić oddzielne accessor nazwy do czytania i pisania slotu.

(defclass Box ()
   ((length :reader get-length :writer set-length)
      (breadth :reader get-breadth :writer set-breadth)
      (height :reader get-height :writer set-height)
   )
)

Tworzenie instancji klasy

Funkcja ogólna make-instance tworzy i zwraca nowe wystąpienie klasy.

Ma następującą składnię -

(make-instance class {initarg value}*)

Przykład

Utwórzmy klasę Box z trzema szczelinami, długością, szerokością i wysokością. Do ustawienia wartości w tych polach użyjemy trzech metod dostępu do gniazd.

Utwórz nowy plik kodu źródłowego o nazwie main.lisp i wpisz w nim następujący kod.

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

Po wykonaniu kodu zwraca następujący wynik -

Length of the Box is 10
Breadth of the Box is 10
Height of the Box is 5

Definiowanie metody klasowej

Plik defmethodmakro umożliwia zdefiniowanie metody wewnątrz klasy. Poniższy przykład rozszerza naszą klasę Box o metodę o nazwie volume.

Utwórz nowy plik kodu źródłowego o nazwie main.lisp i wpisz w nim następujący kod.

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

Po wykonaniu kodu zwraca następujący wynik -

Length of the Box is 10
Breadth of the Box is 10
Height of the Box is 5
Volume of the Box is 500

Dziedzictwo

LISP umożliwia zdefiniowanie obiektu w kategoriach innego obiektu. To się nazywainheritance.Możesz utworzyć klasę pochodną, ​​dodając funkcje, które są nowe lub inne. Klasa pochodna dziedziczy funkcjonalności klasy nadrzędnej.

Poniższy przykład wyjaśnia to -

Przykład

Utwórz nowy plik kodu źródłowego o nazwie main.lisp i wpisz w nim następujący kod.

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

Po wykonaniu kodu zwraca następujący wynik -

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