“overriding”:超类(CLOS)的defclass中的initform设置

时间:2016-02-17 20:33:27

标签: inheritance common-lisp

我有一个使用:initform

定义的类
(defclass A()
  ((MI :initarg :mi :initform (error "must specify mi") ) ) )

它带有一个initialize-instance:after计算一些东西的方法(显示时间太长);该计算的最终结果与A类和派生B类相关;见下文)

和派生类

(defclass B(A)
  (( ABC :initarg :abc :initform (error "must specify abc") ) ) ) 

现在,B类需要在各自的initialize-instance方法中执行与A相同的计算;但是,在这种情况下,A中的参数mi是B中ABC的函数。

所以我试图在B的initalize-instance中计算一个“临时mi”;没用?

我试图计算mi,将它存储在B的ABC的局部变量mitmp中并调用(call-next-method mitmp);没用?

我尝试在B中定义另一个MI字段而没有:如在A中的:initform。我希望我能够在B的initialize-instance中的let-form中计算mi;也没用。

[使用像C ++这样的Blub语言,这可行;不知何故,我坚持这种思维方式。]

所以我留下了一个问题“我怎么能让B有一个强制性的参数ABC,而不是”转换“成强制性A的mi并且给予A的初始化实例。

任何提示都非常受欢迎。

[编辑:澄清一些东西]

1 个答案:

答案 0 :(得分:3)

您可以在:before s b上定义initialize-instance方法。如果您使用:after方法,则仅在a初始化后才会运行。一个简单的例子:

(defclass a ()
  ((mi :initarg :mi :initform (error "Must specify mi"))
   (computed-value :accessor computed-value)))

(defmethod initialize-instance :after ((a a) &key)
  (with-slots (mi computed-value) a
    (setf computed-value (* mi 2))))

(defclass b (a)
  ((abc :initarg :abc :initform (error "must specify abc"))))

(defmethod initialize-instance :before ((b b) &key (abc 1 abc-p))
  ;; You have to check that ABC was given manually, since this is
  ;; run before initialising B. You wouldn't necessarily even 
  ;; need to have a slot for ABC if you don't need it for anything 
  ;; else.
  (unless abc-p (error "Must specify abc"))
  (setf (slot-value b 'mi) (+ abc 10)))

(computed-value (make-instance 'a :mi 4))
; => 8
(computed-value (make-instance 'b :abc 4))
; => 28