LISP - CHIUDI

Il LISP comune ha preceduto il progresso della programmazione orientata agli oggetti di due decenni. Tuttavia, l'orientamento agli oggetti è stato incorporato in una fase successiva.

Definizione di classi

Il defclassmacro permette di creare classi definite dall'utente. Stabilisce una classe come tipo di dati. Ha la seguente sintassi:

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

Gli slot sono variabili che memorizzano dati o campi.

Una descrizione dello slot ha la forma (slot-name slot-option *), dove ogni opzione è una parola chiave seguita da un nome, un'espressione e altre opzioni. Le opzioni di slot più comunemente utilizzate sono:

  • :accessor nome-funzione

  • :initform espressione

  • :initarg simbolo

Ad esempio, definiamo una classe Box, con tre slot di lunghezza, larghezza e altezza.

(defclass Box () 
   (length 
   breadth 
   height)
)

Fornire accesso e controllo di lettura / scrittura a uno slot

A meno che gli slot non abbiano valori a cui è possibile accedere, leggere o scrivere, le classi sono piuttosto inutili.

Puoi specificare accessorsper ogni slot quando si definisce una classe. Ad esempio, prendi la nostra classe Box -

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

Puoi anche specificare separato accessor nomi per leggere e scrivere uno slot.

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

Creazione di istanze di una classe

La funzione generica make-instance crea e restituisce una nuova istanza di una classe.

Ha la seguente sintassi:

(make-instance class {initarg value}*)

Esempio

Creiamo una classe Box, con tre slot, lunghezza, larghezza e altezza. Useremo tre funzioni di accesso agli slot per impostare i valori in questi campi.

Crea un nuovo file di codice sorgente denominato main.lisp e digita il codice seguente.

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

Quando esegui il codice, restituisce il seguente risultato:

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

Definizione di un metodo di classe

Il defmethodmacro consente di definire un metodo all'interno della classe. L'esempio seguente estende la nostra classe Box per includere un metodo denominato volume.

Crea un nuovo file di codice sorgente denominato main.lisp e digita il codice seguente.

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

Quando esegui il codice, restituisce il seguente risultato:

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

Eredità

LISP ti consente di definire un oggetto in termini di un altro oggetto. Questo è chiamatoinheritance.È possibile creare una classe derivata aggiungendo funzionalità nuove o diverse. La classe derivata eredita le funzionalità della classe genitore.

Il seguente esempio spiega questo:

Esempio

Crea un nuovo file di codice sorgente denominato main.lisp e digita il codice seguente.

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

Quando esegui il codice, restituisce il seguente risultato:

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