gpt4 book ai didi

inheritance - CLOS:如何调用一个不太具体的方法?

转载 作者:行者123 更新时间:2023-12-03 22:44:22 25 4
gpt4 key购买 nike

有一个通用方法,比如 incx . incx有两个版本.一种专攻类型 a ,还有一个专门针对类型 b .类型 ba 的子类.你得到一个类型为 b 的对象,派生类型 - 但您想调用专门用于类型 a 的方法.如果还没有专门用于类型 b 的同名方法,您可以轻松地做到这一点。 ,不过唉,居然有这样的方法。

那么如何调用专用于类型 a 的方法?在这种情况下?

(defclass a () ((x :accessor x :initform 0)))
(defclass b (a) ((y :accessor y :initform 0)))

(defgeneric inc (i))

(defmethod inc ((i a)) (incf (x i)))
(defmethod inc ((i b)) (incf (y i)))

(defvar r (make-instance 'b))

正如 CLOS 所 promise 的,这调用了最专业的方法:
* (inc r) 
* (describe r)
..
Slots with :INSTANCE allocation:
X = 0
Y = 1

但是在这种特殊情况下,(不是一般情况下)我想要的是访问不太专业的版本。像这样说:
(inc (r a)) ; crashes and burns of course, no function r or variable a
(inc a::r) ; of course there is no such scoping operator in CL

我看到了 call-next-method函数可以从一个专门的方法中使用来获得下一个不那么专门的方法,但这不是这里想要的。

在删除的代码中,我确实需要类似于 call-next-method 的内容。 ,但用于调用补充方法。我们不需要在下一个不太专业的类中调用同名的方法,而是需要调用它的补充方法,它具有不同的名称。补充方法也是专门的,但调用这个专门的版本不起作用 - 与 call-next-method 的原因大致相同。可能被包括在内。专用于父类(super class)的所需方法并不总是具有相同的名称。
(call-next-method my-complement)  ; doesn't work, thinks my-complement is an arg

这是另一个例子 .

有一个描述电子特性的基类和一个描述“奇怪电子”特性的派生类。专门针对奇怪电子的方法希望调用专门针对电子的方法。为什么?因为这些方法为程序做了正常的电子部分工作。奇怪电子的非电子部分几乎是微不足道的,或者更确切地说,如果它没有复制电子代码:
(defgeneric apply-velocity (particle velocity))
(defgeneric flip-spin (particle))

;;;; SIMPLE ELECTRONS

(defclass electron ()
((mass
:initform 9.11e-31
:accessor mass)
(spin
:initform -1
:accessor spin)))

(defmacro sq (x) `(* ,x ,x))

(defmethod apply-velocity ((particle electron) v)
;; stands in for a long formula/program we don't want to type again:
(setf (mass particle)
(* (mass particle) (sqrt (- 1 (sq (/ v 3e8)))))))

(defmethod flip-spin ((particle electron))
(setf (spin particle) (- (spin particle))))

;;;; STRANGE ELECTRONS

(defclass strange-electron (electron)
((hidden-state
:initform 1
:accessor hidden-state)))

(defmethod flip-spin ((particle strange-electron))
(cond
((= (hidden-state particle) 1)
(call-next-method)

;; CALL ELECTRON'S APPLY-VELOCITY HERE to update
;; the electron. But how???
)
(t nil)))

;; changing the velocity of strange electrons has linear affect!
;; it also flips the spin without reguard to the hidden state!
(defmethod apply-velocity ((particle strange-electron) v)
(setf (mass particle) (* (/ 8 10) (mass particle)))

;; CALL ELECTRON'S SPIN FLIP HERE - must be good performance,
;; as this occurs in critical loop code, i.e compiler needs to remove
;; fluff, not search inheritance lists at run time
)

这一切都归结为一个简单的问题:

如果定义了更专业的方法,如何调用不太专业的方法?

最佳答案

我更喜欢这里的显式方法:

(defun actually-inc-a (value) (incf (x value)))
(defun actually-inc-b (value) (incf (y value)))

(defmethod inc ((object a)) (actually-inc-a object))
(defmethod inc ((object b)) (actually-inc-b object))

即,将要共享的实现部分放入单独的函数中。
(defun apply-velocity-for-simple-electron (particle v)
(setf (mass particle) (* (mass particle) (sqrt (- 1 (sq (/ v 3e8)))))))

(defun flip-spin-for-simple-electron (particle)
(setf (spin particle) (- (spin particle))))

(defmethod apply-velocity ((particle electron) v)
(apply-velocity-for-simple-electron particle v))

(defmethod flip-spin ((particle electron))
(flip-spin-for-simple-electron particle))

(defmethod apply-velocity ((particle strange-electron) v)
(setf (mass particle) (* (/ 8 10) (mass particle)))
(flip-spin-for-simple-electron particle))

(defmethod flip-spin ((particle strange-electron))
(when (= (hidden-state particle) 1)
(call-next-method)
(apply-velocity-for-simple-electron particle #| Hu? What's the V here? |#)))

鉴于我对电子一无所知,无论是普通的还是奇怪的,旋转的与否,我真的想不出这些基本辅助函数的有意义的名称。但除此之外...

关于inheritance - CLOS:如何调用一个不太具体的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35171694/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com