Объектно-ориентированное проектирование с примерами

Метаклассы


Как было сказано, любой объект является экземпляром какого-либо класса. Что будет, если мы попробуем и с самими классами обращаться как с объектами? Для этого нам надо ответить на вопрос, что же такое класс класса? Ответ - это метакласс. Иными словами, метакласс - это класс, экземпляры которого суть классы. Метаклассы венчают объектную модель в чисто объектно-ориентированных языках. Соответственно, они есть в Smalltalk и CLOS, но не в C++.

Вот как Робсон мотивирует потребность в метаклассах: "классы доставляют программисту интерфейс для определения объектов. Если так, то желательно, чтобы и сами классы были объектами, так, чтобы ими можно было манипулировать, как всеми остальными описаниями" [49].

В языках типа Smalltalk первичное назначение метакласса - поддержка переменных класса (которые являются общими для всех экземпляров этого класса), операции инициализации переменных класса и создания единичного экземпляра метакласса [50]. По соглашению, метакласс Smalltalk обычно содержит примеры использования его классов. Например, как показано на рис. 3-11, мы могли бы задать переменную класса nextId для метакласса TelemetryData, чтобы вырабатывать идентифицирующие метки при создании каждого экземпляра TelemetryData. Аналогично, мы могли бы определить оператор порождения новых экземпляров класса, который изготавливал бы их, скажем, в некотором предварительно выделенном пуле памяти.

Хотя в C++ метаклассов нет, семантика его конструкторов и деструкторов служит целям, аналогичным тем, что вызвали к жизни метаклассы. C++ имеет средства поддержки и переменных класса, и операций метакласса. Конкретно, в C++ можно описать члены данных или функции класса как статические (static), что будет означать: этот элемент является общим для всех экземпляров класса. Статические члены класса в C++ эквивалентны переменным класса в Smalltalk. Статическая функция-член класса играет роль операций метакласса в Smalltalk.

Как мы уже отмечали, в CLOS аппарат метаклассов еще сильнее чем в Smalltalk.
Через него можно изменять саму семантику элементов: следование классов, обобщенные функции и методы. Главное преимущество - возможность экспериментировать с другими объектно-ориентированными парадигмами и создавать такие инструменты для разработчика, как броузеры классов и объектов.
 



Рис. 3-11. Метаклассы.

В CLOS есть предопределенный класс с именем standard-class, который является метаклассом для всех нетипизированных классов, определенных с помощью defclass. В этом метаклассе есть метод make-instance, который создает экземпляры. Кроме того, в нем определена вся техника работы со списком следования классов. Все это можно изменить.

Методы и обобщенные функции в CLOS тоже можно рассматривать как объекты. Так как они несколько отличаются от обычных объектов, то в совокупности объекты, соответствующие классам, методам и обобщенным функциям, называются метаобьектами. Каждый метод является экземпляром предопределенного класса standard-method, а каждая функция является экземпляром предопределенного класса standard-generic-function. Поскольку поведение этих предопределенных классов можно изменить, удается влиять на трактовку методов и обобщенных функций.

3.5. Взаимосвязь классов и объектов.


Содержание раздела