是否可以在现有类中动态添加一个超类

时间:2011-08-15 15:07:24

标签: class lisp common-lisp clos

在Common-Lisp CLOS中

是否可以动态添加一个超类 在现有的课程中。

更新

我想定义一些与某些行为相关联的 defassoc 宏 使用相同参数的方法/函数

e.g。

(defassoc (gname (s (g group)))
    ((name1 (name ((corresponding-task task g) s)))
     (record1 (record ((corresponding-task task g) s))))
  (let ((n name1)
        (r record1))
    (if (and name1 record1)
        (display name1 record1)
        (call-next-method))))

扩展到

(symbol-macrolet ((name1 (name ((corresponding-task task g) s)))
                  (record1 (record ((corresponding-task task g) s))))
  (defmethod gname :after (s (g group))
            (let ((n name1) (r record1))
              (if (and name1 record1)
                  (display name1 record1)
                  (call-next-method)))))

这里确保何时(gname(s(g group))被呼叫 这里应该调用相应的任务来分组

(name ((corresponding-task task g) s)
(record ((corresponding-task task g) s)

我用过这个宏

(defmacro defassoc ((main-method main-method-lambda-list)
                    funspec-list &body body)
  `(symbol-macrolet ,(mapcar (lambda (fspec)
                               (destructuring-bind (name f) fspec
                                 (list name f)))
                             funspec-list)
     (defmethod
       ,main-method ,mod ,main-method-lambda-list
       ,@(if body
             body
             `(if (and
                   ,@(mapcar (lambda (e)
                               (car e))
                             funspec-list))
                  (call-next-method)))))

但问题是它会覆盖

(defmethod gname :after (s (g group))
      ...)

(如果有,我可以验证它是否有,)

但是我希望它适用于任何对象,无论是否有覆盖的方法

所以基本上应该需要更改该类和方法中任何东西的代码。

所以有一种方法我决定动态添加父类来定义它的方法。

其他方式可能是 defadvide fwrapper ,但在SBCL中不存在。

1 个答案:

答案 0 :(得分:3)

是的,这是可能的。最简单的方法是简单地重新定义课程。你通过发出另一个DEFCLASS的电话来做到这一点。如果你想做更复杂的事情,你必须求助于MOP(MetaObject Protocol)。基本上你想做的一切都可以使用MOP,但是我需要更详细的信息来说明你要做的是为了进一步解释它。