common-lisp
CLOS - Common Lispオブジェクトシステム
サーチ…
親なしの基本CLOSクラスの作成
CLOSクラスは、次のように記述されます。
- 名前
- スーパークラスのリスト
- スロットのリスト
- ドキュメントのようなさらなるオプション
各スロットには、
- 名前
- 初期化形式(オプション)
- 初期化引数(オプション)
- タイプ(オプション)
- ドキュメント文字列(オプション)
- アクセッサ、リーダおよび/またはライタの機能(オプション)
- 割り当てのようなさらなるオプション
例:
(defclass person ()
((name
:initform "Erika Mustermann"
:initarg :name
:type string
:documentation "the name of a person"
:accessor person-name)
(age
:initform 25
:initarg :age
:type number
:documentation "the age of a person"
:accessor person-age))
(:documentation "a CLOS class for persons with name and age"))
デフォルトの印刷方法:
(defmethod print-object ((p person) stream)
"The default print-object method for a person"
(print-unreadable-object (p stream :type t :identity t)
(with-slots (name age) p
(format stream "Name: ~a, age: ~a" name age))))
インスタンスの作成:
CL-USER > (make-instance 'person)
#<PERSON Name: Erika Mustermann, age: 25 4020169AB3>
CL-USER > (make-instance 'person :name "Max Mustermann" :age 24)
#<PERSON Name: Max Mustermann, age: 24 4020169FEB>
ミックスインとインターフェイス
Common Lispにはいくつかの言語(Javaなど)があるという意味ではインターフェースを持たず、Common Lispが複数の継承と汎用関数をサポートしているので、そのタイプのインターフェースの必要性は少なくなります。しかし、同じタイプのパターンはmixinクラスを使って簡単に実現できます。この例は、いくつかの対応する汎用関数を持つコレクションインタフェースの仕様を示しています。
;; Specification of the COLLECTION "interface"
(defclass collection () ()
(:documentation "A collection mixin."))
(defgeneric collection-elements (collection)
(:documentation "Returns a list of the elements in the collection."))
(defgeneric collection-add (collection element)
(:documentation "Adds an element to the collection."))
(defgeneric collection-remove (collection element)
(:documentation "Removes the element from the collection, if it is present."))
(defgeneric collection-empty-p (collection)
(:documentation "Returns whether the collection is empty or not."))
(defmethod collection-empty-p ((c collection))
"A 'default' implementation of COLLECTION-EMPTY-P that tests
whether the list returned by COLLECTION-ELEMENTS is the empty
list."
(endp (collection-elements c)))
インターフェイスの実装は、そのスーパークラスの1つとしてmixinを持つ単なるクラスであり、適切な汎用関数の定義です。 (この時点では、mixinクラスは実際にクラスが "インタフェース"を実装する意図を伝えるためだけのものであることに注意してください。この例では、いくつかの汎用関数と、関数に関するメソッドがありますクラス。)
;; Implementation of a sorted-set class
(defclass sorted-set (collection)
((predicate
:initarg :predicate
:reader sorted-set-predicate)
(test
:initarg :test
:initform 'eql
:reader sorted-set-test)
(elements
:initform '()
:accessor sorted-set-elements
;; We can "implement" the COLLECTION-ELEMENTS function, that is,
;; define a method on COLLECTION-ELEMENTS, simply by making it
;; a reader (or accessor) for the slot.
:reader collection-elements)))
(defmethod collection-add ((ss sorted-set) element)
(unless (member element (sorted-set-elements ss)
:test (sorted-set-test ss))
(setf (sorted-set-elements ss)
(merge 'list
(list element)
(sorted-set-elements ss)
(sorted-set-predicate ss)))))
(defmethod collection-remove ((ss sorted-set) element)
(setf (sorted-set-elements ss)
(delete element (sorted-set-elements ss))))
最後に、 sorted-setクラスのインスタンスを "interface"関数を使用するときのように使用することができます。
(let ((ss (make-instance 'sorted-set :predicate '<)))
(collection-add ss 3)
(collection-add ss 4)
(collection-add ss 5)
(collection-add ss 3)
(collection-remove ss 5)
(collection-elements ss))
;; => (3 4)
Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow