Dav*_*rse 4 oop common-lisp clos ansi-common-lisp
我想在类对象上定义方法,这些方法基于类的祖先继承,实例方法的继承方式相同。有什么办法可以做到这一点?
这是行不通的:eql-方法专门化。考虑以下示例:
(defclass animal ()())
(defclass bird (animal)())
(defclass woodpecker (bird)())
(defmethod wings-p ((animal-class (eql (find-class 'animal)))) nil)
(defmethod wings-p ((bird-class (eql (find-class 'bird)))) t)
Run Code Online (Sandbox Code Playgroud)
调用会(wings-p (find-class 'woodpecker))生成一个no-method-error,您会看到原因- 对于任何方法专门化器,类woodpecker显然都不eql是。
我想定义“方法” bird,animal以便当我调用wings-p时(find-class woodpecker),wings-p返回t。
我觉得这几乎是所有其他OO系统的标准功能,但是我不记得如何使用CLOS做到这一点。
的确有通过返回的对象之间没有直接的继承链 (find-class 'bird),并(find-class 'woodpecker)说,就像你不能指望一个通用功能的专用只在(eql 1)与(eql 2)给定值3时,产生的结果。
在您的情况下,您可以从导出元类STANDARD-CLASS。您也需要定义方法VALIDATE-SUPERCLASS,然后可以定义自己的具有适当:metaclass参数的类。例如,(find-class 'animal)将返回的实例animal-class。然后,(eql (find-class 'animal))您将不再专注于animal-class。更确切地说:
(defpackage :meta-zoo (:use :closer-common-lisp))
(in-package :meta-zoo)
(defclass animal-class (standard-class) ())
(defclass bird-class (animal-class) ())
(defclass woodpecker-class (bird-class) ())
(defmethod validate-superclass ((class animal-class)
(super standard-class)) t)
(defclass animal () () (:metaclass animal-class))
(defclass bird () () (:metaclass bird-class))
(defclass woodpecker () () (:metaclass woodpecker-class))
(defgeneric class-wing-p (class)
(:method ((a animal-class)) nil)
(:method ((b bird-class)) t))
(defparameter *woody* (make-instance 'woodpecker))
(class-of *woody*)
;; => #<woodpecker-class woodpecker>
(class-wing-p (class-of *woody*))
;; => t
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
433 次 |
| 最近记录: |