你將不能夠輕鬆地執行僅使用CLOS調度這個確切的任務。
在我繼續之前,我認爲關於術語的一些簡要說明很重要。
的Common Lisp的HyperSpec詞彙defines 「子類」 中這樣說:
從另一個類繼承的類,稱爲超類。 (無 類是自身的子類。)
這個定義,而直觀,似乎有些奇怪我爲我期望這是一個「適當的子類」的定義。然而,所有的類都是類型,它defines「子」爲:
類型,其成員是相同的或其他類型的成員的一個子集,被稱爲超類型。 (每種類型都是它自己的子類型。)
請注意括號:「每種類型都是它自己的子類型。「
它還defines一個‘適當的子類型’:
這是不相同的類型的類型的類型的子類型(的類型)(即,其元素是一個``適當子集'' 的類型)。
所以,在你的例子,B和C是A的子類,並且還亞型。在另一方面B,C,和A是A.
亞型
放在德的東西fmethod是"parameter specializer name"。它可以是一個符號,一個類(這有點難),或者一個以eql開頭的列表。如果您提供了一個符號,它將指定由該符號命名的類(當然,這是一個類型)。一個eql列表指定了一個類型,這個對象是列表中東西的eql。
該方法將匹配任何對象,該對象是特化器指定類型的成員。當然,X的子類型的成員也是X的成員。因此,您的第一個問題是您將符號對象傳遞給您的方法;每個符號的類型是SYMBOL
。碰巧命名一個班級的符號在這方面也不例外;它只與類的關係是它是類的名稱,而不是子類型關係。
還有一些類對象(由find-class
返回),但它們並不比方法專用化的符號更好,因爲類對象的類型通常與其子類的類對象的類型相同。
因此,您只需使用實例或閱讀AMOP即可瞭解如何創建自己的通用函數類型。
一旦你有一個實例,你可以寫這樣的方法:
(defmethod fun ((param a))
(if (eq (type-of param) 'a)
(call-next-method)
(format t "~a is a subclass of A~%" (type-of param))))
如果你有一個簡單的方法來檢索您的類的實例,你可以寫這個包裝:
(defmethod fun ((param symbol))
(fun (retrieve-instance param)))
然後你就可以通過符號來獲得樂趣並獲得你想要的結果。
如果你想使用AMOP函數(沒有標準規定,但被廣泛使用,見Closer Project),你可以定義retrieve-instance
這樣的:
(defun retrieve-instance (name)
(let ((class (find-class name)))
(unless (class-finalized-p class)
(finalize-inheritance class))
(class-prototype class)))
注意方法分派差不多是隻有class-prototype
的結果是有益的;不要試圖修改它或類似的東西。