スーパークラスのメソッドを呼び出す - lisp-cookbook-ja/common-lisp GitHub Wiki

オブジェクトシステム(CLOS)

スーパークラスのメソッドを呼び出す

スーパークラスのメソッドを呼び出すには、メソッド定義の中で call-next-method を使用します。 標準のメソッド結合(メソッドコンビネーション)では、プライマリメソッドとaroundメソッドの中で call-next-method が利用できます。 また、aroundメソッドを利用した場合 call-next-method を呼びださないとプライマリメソッドが呼びだされません。

(defclass foo () ())
(defclass bar (foo) ())

(defgeneric foo (self))
(defmethod foo ((self foo))
  "foo!!")
(defmethod foo ((self bar))
  (call-next-method))
(defmethod foo :around ((self bar))
  (format nil "<bar>~A</bar>" (call-next-method)))

;; 試してみる
(foo (make-instance 'bar))
;=> "<bar>foo!!</bar>"

標準のメソッド結合以外では、aroundメソッドの中から call-next-method が使用できます。 それ以外から呼び出すとエラーになります。

(defclass foo () ())
(defclass bar (foo) ())

(defgeneric foo-list (self)
  (:method-combination list))
(defmethod foo-list list ((self foo))
  "foo!!")
(defmethod foo-list :around ((self foo))
  (cons "foo:around!!" (call-next-method)))
(defmethod foo-list list ((self bar))
  "bar!!")
(defmethod foo-list :around ((self bar))
  (cons "bar:around!!" (call-next-method)))

;; 試してみる
(foo-list (make-instance 'bar))
;=> ("bar:around!!" "foo:around!!" "bar!!" "foo!!")
⚠️ **GitHub.com Fallback** ⚠️