Что Smalltalk эквивалентен из статических полей и методов Java? IOW, что делают Smalltalker, когда им нужны данные уровня класса и/или методы?
Мы используем методы/переменные экземпляра на стороне класса. Класс - это объект, в конце концов, поэтому у него могут быть методы.
Например, класс Rectangle имеет метод #origin:corner:, поэтому вы можете написать
Rectangle origin: 0@0 corner: 100@100
для создания Rectangle. Это просто сообщение #origin:corner:, посланное объекту под названием Rectangle (класс - это объект!) с двумя Points в качестве параметров.
Переменные экземпляра на стороне класса работают точно так же. Класс, будучи объектом, может иметь переменные экземпляра. Из библиотеки SUnit:
TestCase class
instanceVariableNames: 'history'
и затем класс TestCase раскрывает это обычным способом, с помощью getter/setter (#history и #history:).
EDIT: @
, который я использовал, вызвал довольно много дискуссий. Это так называемое бинарное сообщение, которое позволяет определять селекторы, которые выглядят так же, как в других языках называются инфиксные операторы. Например, 3 + 4
, или 0@0
. В случае @
класс Number
определяет метод @
, принимающий параметр y
, который определяется как ^Point x: self y: y
- "вернуть точку, координата x которой является моим собственным значением, а координата y - параметром".
Point - это упорядоченная пара, но, конечно, ничто не мешает определить более высокоразмерные версии. Point
может определить метод под названием @
, который выглядит, например, так: ^Triple x: self x y: self y z: z
- "вернуть точку в R^3, чьи координаты x, y - мои собственные, а координата z - заданный параметр".
В большинстве типов Smalltalk у вас есть переменные класса. Обычно переменные класса используются, например, для синглтоны . Однако существуют различия в типах переменных, которые вы можете использовать между разновидностями Smalltalk, поэтому прочтите документацию по этому вопросу для вашей конкретной реализации.
Самое важное переосмысление, которое необходимо сделать, если вы пришли к Smalltalk с Java или чего-то подобного, заключается в том, что классы являются объектами.
Статика в Java-подобных языках может иметь различную семантику.Обычно это связано с видимостью. Вам нужен объект, независимый от каких-либо экземпляров класса, но вы хотите ограничить видимость этого объекта внутри класса, то есть видимым только из экземпляров класса или самого класса (в Smalltalk, потому что в Java классы не являются объектами первого класса).
В Smalltalk у вас обычно есть больше вариантов для этого:
Переменная экземпляра класса действительно похожа на переменную экземпляра экземпляров. любого класса: у класса есть это свойство, и его можно сделать доступным для любого экземпляра класса, предоставив метод получения для класса (не для экземпляров, мы называем это методом класса). Это полезно, если у вас есть значения по умолчанию и тому подобное. Пример:
Определите класс Car
, с переменной экземпляра color
, ПЛЮС переменную экземпляра класса defaultColour
(которая, конечно, будет иметь значение «BLACK» ;-))
Smalltalk defineClass: #Car
superclass: #{Core.Object}
indexedType: #none
private: false
instanceVariableNames: 'colour '
classInstanceVariableNames: 'defaultColour'
imports: ''
category: ''
Это определение класса (фактически сообщение объекту Smalltalk
) в VisualWorks Smalltalk.
Если вы создаете подкласс Car
, он наследует переменную экземпляра класса defaultColour
, как и обычный объект. Если переменная экземпляра класса defaultColour
имеет значение, подкласс также наследует это значение!