Lisp-clos

提供:Dev Guides
移動先:案内検索

LISP-CLOS

Common LISPは、オブジェクト指向プログラミングの進歩よりも数十年前に先んじました。 ただし、オブジェクト指向は後の段階で組み込まれました。

クラスの定義

*defclass* マクロを使用すると、ユーザー定義のクラスを作成できます。 クラスをデータ型として確立します。 次の構文があります-
(defclass class-name (superclass-name*)
   (slot-description*)
   class-option*))

スロットは、データまたはフィールドを格納する変数です。

スロット記述の形式は(slot-name slot-option *)です。各オプションは、名前、式、その他のオプションが続くキーワードです。 最も一般的に使用されるスロットオプションは-

  • *:accessor *関数名
  • *:initform *式
  • *:initarg *シンボル

たとえば、3つのスロットの長さ、幅、高さを持つBoxクラスを定義してみましょう。

(defclass Box ()
   (length
   breadth
   height)
)

スロットへのアクセスおよび読み取り/書き込み制御の提供

スロットにアクセス、読み取り、または書き込みできる値がない限り、クラスはほとんど役に立ちません。

クラスを定義するときに、各スロットに accessors を指定できます。 たとえば、私たちのBoxクラスを取ります-

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

スロットの読み取りと書き込みに別々の accessor 名を指定することもできます。

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

長さ、幅、高さの3つのスロットを持つBoxクラスを作成しましょう。 これらのフィールドに値を設定するには、3つのスロットアクセサーを使用します。

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では、オブジェクトを別のオブジェクトの観点から定義できます。 これは* inheritance。*と呼ばれます。新しいまたは異なる機能を追加することで、派生クラスを作成できます。 派生クラスは、親クラスの機能を継承します。

次の例はこれを説明します-

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