【问题标题】:How to "cast" an instance to a subclass?如何将实例“转换”为子类?
【发布时间】:2017-07-12 06:48:12
【问题描述】:

我有一个类消息实例,我称之为“msg”。我已经定义了一个类“my-message”,并希望实例“msg”现在属于该类。

在我看来它应该相对简单,但我不知道该怎么做。 change-class 给了我一个我不明白的错误。

(defclass my-message (message)
  ((account-name :accessor account-name :initform nil :initarg :account-name)))

(change-class msg 'my-message :account-name account-name)

ERROR :
While computing the class precedence list of the class named MW::MY-MESSAGE.
The class named MW::MESSAGE is a forward referenced class.
The class named MW::MESSAGE is a direct superclass of the class named MW::MY-MESSAGE.

【问题讨论】:

  • 你说你有一个msg类的实例。在您的代码中,您使用一个类message。此类message 定义在哪里?

标签: common-lisp clos


【解决方案1】:
The class named MW::MESSAGE is a forward referenced class.

前向引用类是您引用但尚未定义的类。如果您查看类的名称,它是MW::MESSAGE。我想你想在另一个包中继承另一个名为 MESSAGE 的类;您导入的符号可能有问题。

The class named MW::MESSAGE is a direct superclass of the class named MW::MY-MESSAGE.

由于MW::MESSAGE 类尚未定义,您无法创建它的实例。这也是为什么您不能为其任何子类创建实例的原因,例如MW::MY-MESSAGE

【讨论】:

  • 确实是符号问题。我错过了“前向引用类”是什么。非常感谢!
【解决方案2】:

这对我有用:

CL-USER>  (defclass message () ())
#<STANDARD-CLASS COMMON-LISP-USER::MESSAGE>

CL-USER> (defparameter *msg* (make-instance 'message))
*MSG*

CL-USER> (describe *msg*)
#<MESSAGE {1002FE43F3}>
  [standard-object]
No slots.


CL-USER> (defclass my-message (message)
           ((account-name :accessor account-name
                          :initform nil
                          :initarg :account-name)))
#<STANDARD-CLASS COMMON-LISP-USER::MY-MESSAGE>

CL-USER> (change-class *msg* 'my-message  :account-name "foo")
#<MY-MESSAGE {1002FE43F3}>

CL-USER> (describe *msg*)
#<MY-MESSAGE {1002FE43F3}>
  [standard-object]

Slots with :INSTANCE allocation:
  ACCOUNT-NAME  = "foo"

注意这不是cast,因为对象本身会被改变。它现在是另一个类的实例。 casting 通常意味着在某些上下文中只是对未更改事物的解释发生了变化。但是这里的实例确实发生了变化,旧的解释不再适用。

【讨论】:

    猜你喜欢
    • 2015-05-29
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 2020-07-14
    • 1970-01-01
    • 1970-01-01
    • 2014-01-30
    相关资源
    最近更新 更多