GNU Smalltalk: проблема с примером в учебнике (создание объекта) - PullRequest
2 голосов
/ 10 апреля 2011

Я попытался запустить пример GNU Smalltalk в документации, но столкнулся с проблемой.

Object subclass: Account [
  | balance |
  new [
    | r |
    r := super new.
    r init.
    ^r
  ]
  init [
    'initialize account' printNl.
    balance := 0
  ]
  get [
    ^balance
  ]
]

В методе new сообщение init никогда не отправляется методу Account. Вот мой вывод:

st> Account new get
nil
st> Account new init get
'initialize account'
0

Я взял этот пример из документации GNU Smalltalk .

Может кто-нибудь помочь мне определить ошибку? Я предположил, что, возможно, вызывается метод init для super, но Object не имеет метода init. Кроме того, super должен создать экземпляр текущего класса?

Спасибо Бенджамину за ответ

Поэтому моя проблема заключалась в том, что я не различал функции класса (new) и функции объекта

Фиксированный код

Object subclass: Account [
  | balance |
  init [ balance := 0 ]
  get [ ^balance ]
]
Account class extend [
  new [ ^ (super new init) ]
]


st> Account new get
0

Ответы [ 3 ]

3 голосов
/ 11 апреля 2011

В код внесено небольшое изменение, означающее, что он не будет работать.

В Smalltalk методы могут быть прикреплены в одном из двух мест: они могут применяться к экземплярам. класса, который в данном случае будет объектом учетной записи (например, тот, который вы получите при запуске Account new), или они могут быть class методами, что означает, что они применяются к фактическому классуСам по себе Account.

Account init является методом экземпляра.Он устанавливает некоторые разумные значения по умолчанию для экземпляра класса Account, который вы создали.Вы написали это правильно, и он ведет себя так, как и должен.

С другой стороны, вы изменили Account new с метода класса на метод экземпляра.Когда это метод класса, он заменяет Account существующий new метод на тот, который вызывает init.Когда это метод экземпляра, он на самом деле ничего не делает, так как вы не собираетесь вызывать new для экземпляра.

Исправление достаточно простое: скажите GNU Smalltalk, что newМетод - это метод класса.Чтобы сделать это, вы просто помещаете метод в Account class >> new, а не в класс Account.

2 голосов
/ 10 апреля 2011

Первый new должен быть Account class >> new.Спасибо!

1 голос
/ 13 апреля 2011

Другая возможность:

Object subclass: Account [
    | balance |
    Account class [
        new [
          ...
        ]

        otherClassMethod [
          ...
        ]
    ]

    instanceMethod [
      ...
    ]
]
...