返回介绍

5.3 类

发布于 2025-02-20 00:17:08 字数 2392 浏览 0 评论 0 收藏 0

虽然我们的确实现了方法定义的共享,但是这个解决方案并不理想。为什么?观察对象的定义(上述 (λ (msg . args) ....) 的函数体)。在那里实现的逻辑在所有用 make-point 创建对象中都是重复的:每个对象都有它自己的副本,当它收到 -read 消息时,在 fields 字典中查找; -write 消息时,更新 fields 字典;任何其他消息,查找 methods 表,然后应用对应方法。

所以说,所有这些逻辑在对象之间都可以共享。对象体中唯一的自由变量是 fieldsself 。换句话说,我们可以把对象定义为它自己外加它的字段,而把所有其他的逻辑都交给 make-point 函数。这样的话, make-point 的功能不再是单一的只负责创建新的对象,还负责处理对字段的访问和对消息的处理。也就是说, make-point 演变成所谓的 (class)。

我们如何表示类?目前它只是可以调用的函数(它会创建对象——一个 实例 );如果需要该函数有不同的行为,我们可以应用本书开始时看到的 对象模式 。

在某些语言中,类本身就是对象。这方面的范例就是 Smalltalk。绝对值得花时间一学!

于是:

(define Point
  ....
  (λ (msg . args)
    (case msg
      [(create) create instance]
      [(read) read field]
      [(write) write field]
      [(invoke) invoke method])))

这种模式明确了类的作用:它产生对象,调用方法,读取和写入其实例的字段。

现在,对象的作用是什么?他只需要有标识(identity)功能,知道自己属于哪个类,并记录自己的字段值。它不再自带任何行为。换种说法,对象可以定义为普通的数据结构:

(define-struct obj (class values))

接下来看看现在该怎么定义 Point 类:

(define Point
  (let ([methods ....])
    (letrec
        ([class
             (λ (msg . vals)
               (case msg
                 [(create) (let ((values (make-hash '((x . 0)))))
                             (make-obj class values))]
                 [(read) (dict-ref (obj-values (first vals))
                                   (second vals))]
                 [(write) (dict-set! (obj-values (first vals))
                                     (second vals)
                                     (third vals))]
                 [(invoke)
                   (let ((found (assoc (second vals) methods)))
                     (if found
                         (apply ((cdr found) (first vals)) (cddr vals))
                         (error "message not understood")))]))])
      class)))

> (Point 'create)
#<obj>

要实例化 Point 类,只需向其发送 create 消息。现在对象是结构体了,我们需要一种方法来发送消息,还有访问其字段。要向对象 p 发送消息,先要检索它的类,然后给这个类发送 invoke 消息:

((obj-class p) 'invoke p 'x?)

访问字段也是类似。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文