我有一个使用: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的初始化实例。
任何提示都非常受欢迎。
[编辑:澄清一些东西]
答案 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