3

我来自 Java 和 Python,很难理解 Racket 中面向对象的代码是如何工作的。

  1. 给定

    (define food%
     (class object%
        (super-new)
        (init-field name)
        (field (edible? #t))
        (init-field healthy?)
        (init-field tasty?) ) )
    

    定义一个总有健康的超类水果%的食物%?#t 的值,哪个不需要设置健康?定义新水果时的字段。

  2. 在 racket/gui 中,定义一个名为 text-input-button% 的 button% 超类,它有两个新字段,output(理想情况下是 text-field% 类型)和 text(理想情况下是字符串),其回调字段为它的值是一个函数,它将文本字段的值附加到输出字段值的当前内容。实际上,按钮会将字符输入到指定的文本字段中。

我想如果我能看到这两个例子,我的很多困惑就会得到解决。话虽如此,我正在寻找这样做的“正确”或教科书方法,而不是使用 set! 的一些迂回技巧,除非归结为正确的方法。

4

1 回答 1

4

(1) 你真的是说fruit%应该是 的超类food%吗?在我看来,你想fruit%成为一个子类。这里假设它是一个子类:

(define fruit%
  (class food%
    (super-new [healthy? #t])))

(2) 为此,我认为最好基于 a 创建一个新的小部件panel%来存储两个子小部件:

(define text-input-button%
  (class horizontal-panel%
    (super-new)
    (init-field text)
    ;; callback for the button
    (define (callback button event)
      (define new-value (string-append (send output get-value) text))
      (send output set-value new-value))
    (define button (new button% [label "Click me"]
                                [parent this]
                                [callback callback]))
    (define output (new text-field% [label "Output"]
                                    [parent this]))))

;; testing it out
(define f (new frame% [label "Test"]))
(define tib (new text-input-button% [text "foo"] [parent f]))
(send f show #t)

如果你真的想让它成为 的子类button%,你可以,但我认为这更干净。

于 2013-08-11T22:46:21.043 回答