среда, 9 сентября 2009 г.

Классы и метаклассы --- часть 1

"Мета" = "о"
"Метакласс"= "класс о классе"


Smalltalk построен на нескольких базовых принципах. Два из них: (*) все является объектом и (**) каждый объект является экземпляром некоторого класса, описывающего поведение всех своих экземпляров.

Из этих принципов следует, что (*)=> каждый класс является объектом, и (**)=> является экземпляром некоторого класса --- назовем его метаклассом данного класса.

Рассмотрим некоторый класс C. Экземпляром какого класса он является?

Существует два способа ответить на этот вопрос: (А) все классы являются экземплярами некоторого единственного метакласса, и (Б) каждый класс (в общем случае) является экземпляром некоторого "своего собственного" метакласса.

Поскольку различные классы в Smalltalk обладают различным поведением (см. примечание 1), вариант (А) не подходит, т.к. поведение всех классов будет одинаковым --- оно описано в единственном метаклассе.

Таким образом, класс C является экземпляром своего некоторого собственного, "личного" метакласса.

Чтобы определить, экземпляром какого класса является некоторый объект, ему можно послать сообщение #class. Например:

(Point x: 1 y: 2) class "printIt -> Point"
Point class "printIt -> Point class"


"Личные" метаклассы в Smalltalk не имеют собственного имени (так как ими очень редко пользуются люди) и их текстовое представление совпадает с текстом посылки сообщения на получение метакласса.

Поскольку поведение у всех "личных" метаклассов одинаково, они имеют общий метакласс:

Point class class "printIt -> Metaclass"

Класс Metaclass имеет свое собственное поведение и, соответственно, собственный метакласс:

Metaclass class "printIt -> Metaclass class"

Метакласс класса Metaclass является обычным метаклассом и, соответственно, его метаклассом является Metaclass. "Метаклассом класса Metaclass class является класс Metaclass" :)

--- Примечание 1.
Например, класс Point должен иметь метод #x:y: для создания точки сзаданными координатами:

Point x: 1 y: 2.

Для большинства других классов (String, Integer, Boolean,...) этот метод смысла не имеет.
---

... продолжение следует...

Комментариев нет:

Отправить комментарий