Метакласс (Bymgtlgvv)
Метакласс (англ. Metaclass) — в объектно-ориентированном программировании это класс, экземпляры которого в свою очередь являются классами[1][2].
Поддержка языками программирования
[править | править код]Не все объектно-ориентированные языки программирования поддерживают метаклассы. Те из них, что поддерживают, реализуют разный подход со своими собственным протоколом, правилами создания и обращения[3].
Среди языков, поддерживающих метаклассы:
- Common Lisp и Dylan в составе CLOS
- Groovy
- Object Pascal (особенно Embarcadero Delphi)
- Objective-C
- Python
- Perl, через модуль Moose
- Ruby
- Java
- Smalltalk
Кроме того, существует целый ряд узкоспециализированных, особенно так называемых «академических» языков программирования, поддерживающих и исследующих концепцию метаклассов[4].
Особняком стоит Java, где также есть единственный метакласс — Class (описывает классы), который располагается в библиотеке java.lang. Однако, развитой концепции работы с метаклассами Java не предоставляет.
Поддержка платформами
[править | править код]Метаклассы могут существовать не только как сущность языка программирования, но и как сущность многоязыковой платформы. Наиболее явно метаклассы выражены в IBM System Object Model. Архитекторы SOM учитывали положительные стороны CLOS и решили один из её недостатков, несовместимость метаклассов, уникальным на то время способом. Несовместимость метаклассов — это ситуация, когда метакласс подкласса не является подклассом метакласса. В CLOS это приводит к аварийному завершению. Ситуация может возникнуть, когда разные части системы разрабатываются разными командами, и структура классов одной части системы изменилась, а в другой части системы эти изменения не синхронизированы. Одной из целей SOM являлось обеспечение максимальной совместимости на бинарном уровне между релизами. Инновационным решением, введённым в SOM 2.0 является создание анонимного подкласса нескольких метаклассов в случае, если ни один из метаклассов класса не является подклассом для остальных. В CLOS и SOM 1.0 указание метакласса является требованием. В SOM 2.0 указание метакласса является пожеланием, а реальный метакласс может быть создан во время исполнения, наследуясь от нескольких родителей: от желаемого метакласса, а также от метаклассов каждого надкласса.
Явные и неявные метаклассы
[править | править код]Явные метаклассы указываются при объявлении класса. Разработчик, имея возможность явно указать метакласс, может создавать произвольно сложные иерархии.
Если объектная модель поддерживает только неявные метаклассы, это значит, что синтаксически существует только иерархия классов, но при этом в классах присутствуют так называемые классовые методы. При этом иерархия метаклассов зеркалирует иерархию классов. Обычные методы добавляются в обычный класс, а классовые методы добавляются в соответствующий метакласс, но разработчик не может установить произвольные связи наследования между метаклассами и классами. Классовые методы могут быть настоящими методами, а могут быть «синтаксическим сахаром», то есть, видны, если обращаться к классу по имени, но не видны, если пытаться вызвать их как обычные методы у переменной, которой перед этим была присвоена ссылка на этот же класс.
Зацикленность метаклассов
[править | править код]Цепочка из классов классов классов … в разных объектных моделях ведёт себя по-разному.
В моделях с неявными метаклассами поддерживается зеркалирование иерархий, а, значит, и разделение. Так, в Delphi метаклассы не могут иметь собственное имя, а всегда идентифицируются как «class of …», а поскольку «class of class of …» — синтаксически неверная конструкция, то цепочка заведомо обрывается на метаклассе. В SmallTalk и Objective-C классы, хотя и неявные, но всё же являются объектами, аналогичными обычным, поэтому оборвать цепочку невозможно.
В моделях с явными метаклассами классы — это объекты, поэтому оборвать цепочку тоже невозможно. Если цепочку не обрывать, либо должен существовать специальный базовый класс, сконструированный так, чтобы являться классом для себя самого, либо эта цепочка потенциально бесконечна с созданием очередных метаклассов на лету.
Несовместимость метаклассов
[править | править код]Несовместимость метаклассов — это ситуация, когда метакласс подкласса — не подкласс метакласса. То есть, может существовать какой-то код, работающий с экземплярами класса A, про который известно, что его класс (метакласс его экземпляров) — это класс MA, и у любого объекта класса A можно вызвать классовые методы из MA. Тогда, если вдруг возможно создать экземпляры потомков класса A, не поддерживающих классовые методы из MA, такие экземпляры потомков будут несовместимы с кодом, ожидающим экземпляры A, что противоречит принципам ООП. Чтобы такие скрытые ошибки не происходили, обычно создание таких потомков блокируется.
В моделях с неявными метаклассами за счёт зеркалирования иерархий такая ситуация в принципе исключена. В моделях с явными метаклассами можно либо аварийно завершить программу, либо сконструировать такой метакласс, который был бы потомком для метакласса каждого базового класса и для желаемого метакласса класса. Конечно, для этого необходима поддержка множественного наследования.
Сравнение особенностей
[править | править код]Объектная модель | C++ | Delphi | Java и .NET | SmallTalk и Objective-C | Ruby | CLOS | Python | SOM и PMtW[5] |
---|---|---|---|---|---|---|---|---|
Метаклассы явные? | RTTI | неявные | неявные | неявные | ? | явные | явные | явные |
Класс — это обычный объект? | нет | нет | да | да | ? | да | да | да |
Классовые методы — это методы класса? | нет | да | нет | да | да | да | да | да |
Цепочка из классов классов классов … | обрывается | обрывается | зациклена | зациклена | бесконечна | зациклена | зациклена | зациклена |
Если метакласс подкласса — не подкласс метакласса, то | н/п | н/п | н/п | н/п | ? | ошибка | ошибка | нужный конструируется |
См. также
[править | править код]Примечания
[править | править код]- ↑ Мейер, Бертран «Основы объектно-ориентированного программирования Архивная копия от 21 ноября 2010 на Wayback Machine»
- ↑ Wolfgang Klas, Michael Schrefl Metaclasses and Their Application. Data Model Tailoring and Database Integration. — Berlin; Heidelberg; New York; Barcelona; Budapest; Hong Kong; London; Milan; Paris; Tokyo : Springer, 1995 (Lecture notes in computer science; Vol. 943) ISBN 3-540-60063-9
- ↑ Ira R. Forman and Scott Danforth Putting Metaclasses to Work — 1999. ISBN 0-201-43305-2.
- ↑ Noury Bouraqad Efficient Support for Mixin-Based Inheritance Using Metaclasse Архивная копия от 16 октября 2007 на Wayback Machine.
- ↑ Модель, описанная в книге «Putting Metaclasses to Work» и реализованная в прилагаемой к книге симуляции на Java Архивная копия от 23 июня 2020 на Wayback Machine (для запуска требуется старый JDK).
Литература
[править | править код]- И. Ю. Баженова, «Delphi 7 самоучитель программиста», «Москва» 2003
Ссылки
[править | править код]- Программирование метаклассов в Python (ibm.com)
- LOOPS. Метаклассы ()
- Java. Метакласс
- Публикации Scott H. Danforth и Ira R. Forman, архитекторов метаклассов в System Object Model (англ.)
Для улучшения этой статьи желательно:
|