LISP - CLOS

O LISP comum antecedeu o avanço da programação orientada a objetos por algumas décadas. No entanto, sua orientação a objetos foi incorporada a ela em um estágio posterior.

Definindo Classes

o defclassmacro permite a criação de classes definidas pelo usuário. Ele estabelece uma classe como um tipo de dados. Possui a seguinte sintaxe -

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

Os slots são variáveis ​​que armazenam dados ou campos.

Uma descrição de slot tem a forma (slot-name slot-option *), onde cada opção é uma palavra-chave seguida por um nome, expressão e outras opções. As opções de slot mais comumente usadas são -

  • :accessor nome da função

  • :initform expressão

  • :initarg símbolo

Por exemplo, vamos definir uma classe Box, com três slots de comprimento, largura e altura.

(defclass Box () 
   (length 
   breadth 
   height)
)

Fornecimento de acesso e controle de leitura / gravação para um slot

A menos que os slots tenham valores que podem ser acessados, lidos ou escritos, as classes são bastante inúteis.

Você pode especificar accessorspara cada slot ao definir uma classe. Por exemplo, faça nossa aula Box -

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

Você também pode especificar accessor nomes para ler e escrever um slot.

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

Criação de instância de uma classe

A função genérica make-instance cria e retorna uma nova instância de uma classe.

Possui a seguinte sintaxe -

(make-instance class {initarg value}*)

Exemplo

Vamos criar uma classe Box, com três slots, comprimento, largura e altura. Usaremos três acessores de slot para definir os valores nesses campos.

Crie um novo arquivo de código-fonte denominado main.lisp e digite o seguinte código nele.

(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 você executa o código, ele retorna o seguinte resultado -

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

Definindo um Método de Classe

o defmethodmacro permite que você defina um método dentro da classe. O exemplo a seguir estende nossa classe Box para incluir um método denominado volume.

Crie um novo arquivo de código-fonte denominado main.lisp e digite o seguinte código nele.

(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 você executa o código, ele retorna o seguinte resultado -

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

Herança

LISP permite que você defina um objeto em termos de outro objeto. Isso é chamadoinheritance.Você pode criar uma classe derivada adicionando recursos novos ou diferentes. A classe derivada herda as funcionalidades da classe pai.

O exemplo a seguir explica isso -

Exemplo

Crie um novo arquivo de código-fonte denominado main.lisp e digite o seguinte código nele.

(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 você executa o código, ele retorna o seguinte resultado -

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