- Примесь (программирование)
-
При́месь (англ. mix in) — элемент языка программирования (обычно класс или модуль), реализующий какое-либо чётко выделенное поведение. Используется для уточнения поведения других классов, не предназначен для порождения самостоятельно используемых объектов. В объектно-ориентированных языках программирования является способом реализации классов, отличным от широко используемых принципов, пришедших из языка программирования Simula. Механизм впервые реализован в Flavors. Преимуществом примесей является то, что повышая повторную используемость текстов программ, этот метод избегает многих проблем множественного наследования. Однако при этом метод накладывает свои ограничения.
Содержание
Реализация
В большинстве объектно-ориентированных языков, начиная с Simula класс определяется атрибутами, методами, конструкторами и деструкторами как единое, тесно связанное целое. Определение класса обладает полнотой. Именно этот факт показался полезным Страуструпу и Эллис, которые на этом основании не стали реализовывать примеси в Си++ на уровне языка (Си++ разрабатывался как «совместимое расширение Си в сторону Симулы») .
В языке с использованием примесей класс определяется только с атрибутами и параметрами, связанными с классом. Методы определяются в другом месте, как в Flavors и CLOS, и являются обобщёнными функциями. Последние реализуются для различных типов посредством диспетчеризации.
Кроме Flavors и CLOS, примеси поддерживают следующие языки:
Пример
Использование примесей
Пример на языке Руби. Класс реализует простую концепцию возраста. Значение возраста хранится во внутренней переменной «age», которая открыта для записи и чтения. Для получения возможности сравнения возрастов класс реализует один оператор «<=>», а все остальные (больше, меньше, равно и т. д.) реализуются с использованием этого метода во включаемом модуле «Comparable».
class Age include Comparable attr_accessor(:age) def <=>(cmp) @age <=> cmp.age end end
Пример демонстрирует создание объектов и использование «подмешанных» методов:
a, b = Age.new, Age.new a.age = 10 b.age = 11 if a < b then puts "Да, да, да." end
Эмуляция
Примеси можно рассматривать как неполную реализацию множественного наследования, его частный вид. В языках, поддерживающих множественное наследование, примеси могут легко эмулироваться. Например, в C++ следующий шаблон может использоваться для добавления в класс оператора «!=» при наличии оператора «==»:
template <typename T> struct AddNoEq { virtual bool operator==(const T &cmp) const = 0; bool operator!=(const T &cmp) const { return !static_cast<const T*>(this)->operator== (cmp); } };
Простой пример использования для класса комплексных чисел:
#include <iostream> struct Complex : public AddNoEq<Complex> { Complex(int re, int im): re_(re), im_(im) { } virtual bool operator==(const Complex& cmp) const { return cmp.re_ == this->re_ && cmp.im_ == this->im_; } // ... private: int re_, im_; }; int main() { Complex a(1, 2), b(2, 3); if (a != b) std::cout << "Так и должно быть" << std::endl; return 0; }
Данный метод в более развёрнутом виде используется в библиотеке «Boost operators».
Замечание
Близкую к примесям функциональность предоставляют интерфейсы в языках вроде Java и C#, c тем отличием, что интерфейс только специфицирует поведение, но не предоставляет реализации. Механизм может быть полезен только для представления полиморфизма. Другие классы, предоставляющие реализацию интерфейса, полезны для вынесения общей функциональности в единое место.
Совместно используя методы-расширения и интерфейсы, возможно реализовать функциональность примесей в C#.
Ссылки
- Mix In (англ.) — описание данного метода программирования.
Для улучшения этой статьи желательно?: - Найти и оформить в виде сносок ссылки на авторитетные источники, подтверждающие написанное.
Категории:- Концепции языков программирования
- Объектно-ориентированное программирование
Wikimedia Foundation. 2010.