:
代替、醜い、バージョンは値がハードコードになります。
私が続行する前に、用語に関する簡単な注釈が重要だと思います。このように
Common LispのHyperSpec用語集defines "サブクラス":
別のクラスから継承するクラスは、スーパークラスと呼ばれます。 (NO クラスは、自身のサブクラスではありません。)私は、「適切なサブクラス」の定義であることを期待するよう
この定義は、直感的ながら、私には奇妙に思えます。しかし、すべてのクラスがdefines「サブタイプ」タイプであり、それのように:
その会員と同じまたは別のタイプの会員の適切なサブセットであるタイプ、スーパータイプと呼ばれます。 (すべてのタイプはそれ自身のサブタイプです)
「すべてのタイプはそれ自身のサブタイプです。「
それもdefines 『適切なサブタイプ』:
(タイプの)タイプ(すなわち、同じタイプではないタイプのサブタイプで、その要素は、 ``適切なサブセットであります'タイプの)。
したがって、あなたの例では、B及びCは、Aのサブクラスであり、またサブタイプ一方のBで、C、とはA.
のサブタイプであります
デートに置かれるものfmethodは"parameter specializer name"です。シンボル、クラス(入力するのは少し難しい)、またはeqlで始まるリストにすることができます。シンボルを指定すると、そのシンボルで指定されたクラスが指定されます(これはもちろんタイプです)。 eqlリストは、リスト内のものにeqlであるオブジェクトで構成されるタイプを指定します。
このメソッドは、スペシャライザが指定する型のメンバであるオブジェクトと一致します。もちろん、XのサブタイプのメンバーもXのメンバーです。
最初の問題は、シンボルオブジェクトをメソッドに渡していることです。すべてのシンボルのタイプはSYMBOL
です。クラスに名前をつけるシンボルは、この点で違いはありません。クラスとの唯一の関係はクラスの名前であり、サブタイプの関係ではありません。
クラスオブジェクト(find-class
が返されます)がありますが、クラスオブジェクトの型は通常、そのサブクラスのクラスオブジェクトの型と同じであるため、メソッドの特殊化のシンボルよりも優れていません。
したがって、インスタンスを使用するか、AMOPと読むことで、独自のタイプの汎用関数を作成する方法を学ぶことができます。
インスタンスを持っていたら、このような方法で記述することができます。
(defmethod fun ((param symbol))
(fun (retrieve-instance param)))
:あなたは、クラスのインスタンスを取得する簡単な方法を持っている場合、あなたはこのラッパーを書くことができ
を
(defmethod fun ((param a))
(if (eq (type-of param) 'a)
(call-next-method)
(format t "~a is a subclass of A~%" (type-of param))))
それから、シンボルを楽しいものに渡して、あなたが望む結果を得ることができます。
あなたは(、標準で指定されたが、広く利用されていなかったCloser Projectを参照)AMOP機能を使用する場合は、このようなretrieve-instance
定義することができます:メソッドディスパッチは単なるについてです
(defun retrieve-instance (name)
(let ((class (find-class name)))
(unless (class-finalized-p class)
(finalize-inheritance class))
(class-prototype class)))
注ことをclass-prototype
の結果だけが役に立ちます。それを変更しようとしないでください。