LISP - CLOS



Common LISP 的出現比面向物件程式設計早了幾十年。然而,面向物件特性在後期被整合到其中。

定義類

defclass 宏允許建立使用者自定義類。它將類建立為一種資料型別。其語法如下:

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

槽是儲存資料的變數,或欄位。

槽描述符的形式為 (slot-name slot-option*),其中每個選項都是一個關鍵字,後跟名稱、表示式和其他選項。最常用的槽選項是:

  • :accessor 函式名

  • :initform 表示式

  • :initarg 符號

例如,讓我們定義一個 Box 類,它有三個槽:length、breadth 和 height。

(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 類,它有三個槽:length、breadth 和 height。我們將使用三個槽訪問器來設定這些欄位的值。

建立一個名為 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 允許您根據另一個物件定義物件。這稱為繼承。您可以透過新增新的或不同的特性來建立派生類。派生類繼承父類的功能。

以下示例說明了這一點:

示例

建立一個名為 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
廣告