Common Lisp通過幾十年的物件導向程式設計的推進。但是,物件導向被併入是在它最後一階段。
defclass巨集允許建立使用者定義的類。它建立了一個類作為資料型別。它的語法如下:
(DEFCLASS class-name (superclass-name*) (slot-description*) class-option*)
插槽是儲存資料變數或欄位。
slot-description形式(插槽名稱插槽選項*),其中每個選項是一個關鍵字後跟一個名字,表示式和其他選項。最常用的槽選項是:
:accessor 函式名稱
:initform 表示式
:initarg 符號
例如,讓我們定義一個Box類,有三個槽的長度,廣度和高度。
(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類,有三個插槽,長度,寬度和高度。我們將使用三個插槽存取到這些欄位設定的值。
建立一個名為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