返回介绍

5.5 初始化

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

我们已经看到,要从类获取对象(即实例化对象)的方法是向类发送 create 消息。能够给 create 传递参数,以指定对象的字段的初始值通常是有用的。目前,我们的类系统仅支持在类声明时指定默认字段值。在实例化时没法传递初始字段值。

初始化方法是 Smalltalk 编程中的习惯叫法。在 Java 中,它们被称为构造函数(这可以说是个糟糕的名字,因为我们可以看到,它们并不负责构建对象,只是在实际创建对象之后才对其进行初始化)。

有几种方法可以做到这一点。一个简单的方法是,要求对象实现 初始化 方法,并让这个类在每个新创建的对象上调用此初始化方法。我们将采用如下约定:如果 create 消息没有参数,那么我们不调用初始器(因此使用默认值)。如果有参数传入,我们就用这些参数调用初始器(称之为 initialize ):

....
(λ (msg . vals)
  (case msg
    [(create)
     (if (null? vals)
         (make-obj class
                   (make-hash (list (cons 'f init) ...)))
         (let ((object (make-obj class (make-hash))))
           (apply ((cdr (assoc 'initialize methods)) object) vals)
           object))]
    ....)) ....

我们可以改进实例化类的辅助函数,使其接受可变数目的参数:

(define (new class . init-vals)
    (apply class 'create init-vals))

来试试看:

(define Point
 (CLASS ([field x 0])
        ([method initialize (nx) (-> self x! nx)]
         [method x? () (? x)]
         [method x! (nx) (! x nx)]
         [method move (n) (-> self x! (+ (-> self x?) n))])))

(define p (new Point 5))

> (-> p move 10)
> (-> p x?)
15

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

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

发布评论

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