Common Lisp Object System

редактировать
Стандартная комбинация методов в ANSI common lisp

объектная система Common Lisp (CLOS) - это средство для объектно-ориентированного программирования, которое является частью ANSI Common Lisp. CLOS - это мощная динамическая объектная система, которая радикально отличается от возможностей ООП, имеющихся в более статических языках, таких как C ++ или Java. CLOS был вдохновлен более ранними объектными системами Lisp, такими как MIT Flavors и CommonLoops, хотя он является более общим, чем любой другой. Первоначально предложенный в качестве надстройки, CLOS был принят как часть стандарта ANSI для Common Lisp и был адаптирован для других диалектов Lisp, таких как EuLisp или Emacs Lisp.

Содержание
  • 1 Особенности
  • 2 Протокол метаобъектов
  • 3 Влияния со стороны более старых объектных систем на основе Lisp
  • 4 CLOS в других языках программирования
  • 5 Ссылки
  • 6 Литература
Возможности

основные строительные блоки CLOS - это классы и их методы, экземпляры этих классов и универсальные функции. CLOS предоставляет макросы для их определения: defclass, defmethodи defgeneric. Экземпляры создаются с помощью метода make-instance.

. Классы могут иметь несколько суперклассов, список слотов (переменные-члены на языке C ++ / Java) и специальный метакласс . Слоты могут быть распределены по классам (все экземпляры класса разделяют слот) или по экземплярам. У каждого слота есть имя, и по этому имени можно получить доступ к значению слота, используя функцию значение слота. Дополнительно могут быть определены специальные общие функции для записи или чтения значений слотов. Каждый слот в классе CLOS должен иметь уникальное имя.

CLOS - это система множественной отправки. Это означает, что методы могут быть специализированы на любом или всех их требуемых аргументах. Большинство объектно-ориентированных языков используют однократную отправку, что означает, что методы специализируются только на первом аргументе. Еще одна необычная особенность состоит в том, что методы не «принадлежат» классам; классы не предоставляют пространство имен для универсальных функций или методов. Методы определяются отдельно от классов, и у них нет специального доступа (например, «this», «self» или «protected») к слотам классов.

Методы в CLOS сгруппированы в общие функции. Универсальная функция - это объект, который вызывается как функция и который связывает набор методов с общим именем и структурой аргументов, каждый из которых специализируется на разных аргументах. Поскольку Common Lisp предоставляет классы, отличные от CLOS, для структур и встроенных типов данных (числа, строки, символы, символы,...), диспетчеризация CLOS работает также с этими классами, отличными от CLOS. CLOS также поддерживает отправку по отдельным объектам (специалистам eql). CLOS по умолчанию не поддерживает диспетчеризацию для всех типов данных Common Lisp (например, диспетчеризация не работает для полностью специализированных типов массивов или для типов, представленных в deftype). Однако большинство реализаций Common Lisp предоставляют протокол метаобъектов , который позволяет универсальным функциям предоставлять специфические для приложения правила специализации и диспетчеризации.

Отправка в CLOS также отличается от большинства языков объектно-ориентированного программирования:

  1. По списку аргументов определяется список применимых методов.
  2. Этот список сортируется в соответствии со спецификой их Специализаторы параметров.
  3. Выбранные методы из этого списка затем объединяются в эффективный метод с использованием комбинации методов, используемой универсальной функцией.
  4. Затем эффективный метод вызывается с исходными аргументами.

Этот механизм отправки работает во время выполнения. Таким образом, добавление или удаление методов может привести к изменению эффективных методов (даже если универсальная функция вызывается с теми же аргументами) во время выполнения. Изменение комбинации методов также может привести к другим эффективным методам.

Например,

; объявить прототип структуры общих аргументов (defgeneric f (x y)); определить реализацию для (f integer t), где t соответствует всем типам (defmethod f ((x integer) y) 1) (f 1 2.0) =>1; определить реализацию для (f integer real) (defmethod f ((x integer) (y real)) 2) (f 1 2.0) =>2; диспетчеризация изменена во время выполнения

Как и системы объектно-ориентированного программирования в большинстве динамических языков, CLOS не применяет инкапсуляцию. Доступ к любому слоту можно получить с помощью функции значения слотаили с помощью (опционально автоматически сгенерированных) методов доступа . Чтобы получить к нему доступ через значение слота, вы должны знать имя слота. Программисты CL используют средство пакета языка, чтобы объявить, какие функции или структуры данных предназначены для экспорта.

Помимо обычных («основных») методов, существуют также : до, : послеи : вокруг«вспомогательных» методов.. Первые два вызываются до или после основного метода в определенном порядке, основанном на иерархии классов. Метод : aroundможет контролировать, будет ли выполняться основной метод вообще. Кроме того, программист может указать, должны ли вызываться все возможные основные методы в иерархии классов или только тот, который обеспечивает наиболее близкое соответствие.

Стандартная комбинация методов обеспечивает основные методы, методы до, после и после, описанные выше. Существуют и другие комбинации методов с другими типами методов. Могут быть определены новые (как простые, так и сложные) комбинации методов и типы методов.

CLOS разрешает множественное наследование. Если порядок по умолчанию, в котором методы выполняются при множественном наследовании, неверен, программист может решить проблемы алмазного наследования, указав порядок комбинаций методов.

CLOS является динамическим, что означает, что не только содержимое, но и структура его объектов могут быть изменены во время выполнения. CLOS поддерживает изменение определений классов на лету (даже если экземпляры рассматриваемого класса уже существуют), а также изменение членства в классе данного экземпляра с помощью оператора change-class. CLOS также позволяет добавлять, переопределять и удалять методы во время выполнения. Задача круг-эллипс легко решается в CLOS, и большинство шаблонов проектирования ООП либо исчезают, либо становятся качественно проще.

CLOS не является языком прототипов : классы должны быть определены до того, как объекты могут быть созданы как члены этого класса.

Протокол метаобъектов

Помимо стандарта ANSI Common Lisp существует широко используемое расширение для CLOS, называемое протоколом метаобъектов (MOP). MOP определяет стандартный интерфейс к основам реализации CLOS, рассматривая классы, описания слотов, общие функции и методы как экземпляры метаклассов, и позволяет определять новые метаклассы и изменять все ЗАКРЫТОЕ поведение. Гибкость CLOS MOP предвосхищает аспектно-ориентированное программирование, которое позже было разработано некоторыми из тех же инженеров, такими как Грегор Кичалес. MOP определяет поведение всей объектной системы с помощью набора протоколов. Они определены в терминах CLOS. Таким образом, можно создавать новые объектные системы, расширяя или изменяя предоставленную функциональность CLOS. В книге Искусство протокола метаобъектов описано использование и реализация CLOS MOP.

Различные реализации Common Lisp немного по-разному поддерживают протокол метаобъектов. Проект Closer призван предоставить недостающие функции.

Влияния со стороны более старых объектных систем на основе Lisp

Flavors (и его преемника New Flavors) были объектной системой на MIT Lisp Machine. Большая часть операционных систем Lisp Machine и многие приложения для нее используют разновидности или новые разновидности. Flavors представили, среди прочего, множественное наследование и примеси. Flavors в основном устарели, хотя реализации Common Lisp существуют. Компания Flavors использовала парадигму передачи сообщений. В New Flavors представлены общие функции.

CommonLoops был преемником LOOPS (от Xerox Interlisp -D). CommonLoops был реализован для Common Lisp. Переносимая реализация под названием Portable CommonLoops (PCL) была первой реализацией CLOS. PCL широко переносится и по-прежнему является основой для реализации CLOS нескольких реализаций Common Lisp. PCL реализован в основном на переносимом Common Lisp с несколькими зависимыми от системы частями.

CLOS на других языках программирования

Из-за мощи и выразительности CLOS, а также исторической доступности TinyCLOS (упрощенная переносимая реализация CLOS, написанная Грегором Кичалесом для использования со Scheme), CLOS-подобные объектные системы на основе MOP стали де-факто нормой в большинстве реализаций диалектов Lisp, а также нашли свое применение в некоторых других языках OOP средствах:

Ссылки
Литература
Последняя правка сделана 2021-05-15 07:10:31
Содержание доступно по лицензии CC BY-SA 3.0 (если не указано иное).
Обратная связь: support@alphapedia.ru
Соглашение
О проекте