Mixin против наследования

В чем разница между миксином и наследованием?

10 ответов

Mix in обычно используется с множественным наследованием. Так что, в этом смысле, "нет разницы".

Суть в том, что Mix in редко используется как отдельный объект.

Например, скажем, у вас есть Mix In имя "ColorAndDimension", которое добавляет свойство цвета, ширину и высоту.

Теперь вы можете добавить ColorAndDimension, скажем, в Shape Class, Sprite Class, Car Class и т. Д. И все они будут иметь одинаковый интерфейс (скажем, get/setColor, get/setHeight/Width и т. Д.)

Таким образом, в общем случае Mix in IS наследуется. Но вы можете утверждать, что вопрос о роли класса в общей области в том, является ли Mix in "первичным" классом или просто mix in.

Редактировать - просто уточнить.

Да, Mix In можно рассматривать в современном современном языке как интерфейс со связанной реализацией. Это действительно просто старое, повседневное множественное наследование с использованием простого, старого, повседневного класса. Просто так происходит конкретное применение МИ. Большинство языков не дают смешивания В каком-либо особом статусе, это просто класс, который был разработан, чтобы быть "смешанным", а не использоваться отдельно.

В чем разница между миксином и наследованием?

Миксин - это базовый класс, от которого вы можете наследовать, чтобы обеспечить дополнительную функциональность. Название "mix-in" указывает, что оно предназначено для смешивания с другим кодом. Таким образом, вывод заключается в том, что вы не будете создавать экземпляр встроенного класса самостоятельно. Часто смешивание используется с другими базовыми классами. Поэтому миксины являются подмножеством или частным случаем наследования.

Преимущества использования надстройки над одиночным наследованием состоят в том, что вы можете написать код для функциональности один раз, а затем использовать одну и ту же функциональность в нескольких разных классах. Недостатком является то, что вам, возможно, придется искать эту функциональность в других местах, отличных от тех, где она используется, поэтому полезно уменьшить этот недостаток, держа его рядом.

Лично я обнаружил, что необходимо использовать сочетание по одному наследованию, когда мы тестируем множество одинакового кода, но тестовые случаи создаются на основе их наследования базового случая и единственного способа сохранить код близко hand (и в том же модуле), не связываясь с номерами покрытия, должен наследовать от объекта, а дочерние случаи наследуют как от универсальной базы тестовых наборов, так и от пользовательской базы, которая применяется только к ним.

Mixins в сравнении и контрасте с абстрактными базовыми классами

Оба являются формой родительского класса, который не предназначен для реализации.

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

Абстрактный базовый класс предоставляет интерфейс, но без полезной функциональности. Пользователь предназначен для создания функциональности, вызываемой интерфейсом.

В Python некоторые классы в abc Модуль - это примеры родительских классов, которые предоставляют функциональность через наследование и абстрактные интерфейсы, которые должны быть реализованы подклассом. Эти идеи не являются взаимоисключающими.

Резюме

Проще говоря, встраивание - это просто базовый класс, который вы не будете создавать самостоятельно, и обычно используется как вторичный базовый класс в множественном наследовании.

Вмешательство - это особый, ограниченный случай (множественного) наследования, используемый для целей реализации; некоторые языки (например, Ruby) поддерживают его, не поддерживая обобщенное множественное наследование.

Mixin - это абстрактное понятие, и все, что отвечает его требованиям, может рассматриваться как mixin.

Вот определение из Википедии.

В объектно-ориентированных языках программирования миксин - это класс, который содержит методы для использования другими классами без необходимости быть родительским классом этих других классов. То, как эти другие классы получают доступ к методам миксина, зависит от языка. Миксины иногда описываются как "включенные", а не "унаследованные".

Короче говоря, ключевое отличие от наследования заключается в том, что встраиваемые модули НЕ должны иметь отношения "есть" как в наследовании.

С точки зрения реализации, вы можете рассматривать его как интерфейс с реализациями. Например, абстрактный класс в Java может рассматриваться как миксин, если Java поддерживает множественное наследование.

"Миксин - это фрагмент класса в том смысле, что он предназначен для объединения с другими классами или миксинами". -DDJ

Миксин - это класс или фрагмент кода, который не предназначен для автономного использования, но вместо этого вы должны использовать его внутри другого класса. Составьте его как поле / переменную-член или как сегмент кода. У меня больше всего воздействия на потом. Это немного лучше, чем копирование и вставка стандартного кода.

Вот отличная статья DDJ, которая представляет предмет.

Half-Life 2 / "Source" SDK является отличным примером C++ миксинов. В этой среде макросы определяют значительные блоки кода, которые можно добавить, чтобы придать классу особый "вкус" или особенность.

Посмотрите на пример Source wiki: Создание логической сущности. В примере кода макрос DECLARE_CLASS можно считать миксином. Source SDK широко использует миксины, чтобы стандартизировать код доступа к данным и приписывать поведение объектам.

Миксины широко используются в более "плагиновой" манере.

Они одинаковы, но каждый из них находится в разном контексте. Обычно, когда мы говорим о наследовании, мы говорим об ОДНОМ наследовании, а миксин - это конструкция, которая допускает МНОЖЕСТВЕННОЕ наследование.

Это языковая конструкция, которая вызывает большие споры в мире ООП по следующим причинам:

  • Неопределенность в том, что это необходимо разрешить
  • Часто классы "миксинов" не работают сами по себе и могут конфликтовать с другими миксинами.
  • Это может привести к "проблеме наследования алмазов", когда два суперкласса могут наследовать от одного и того же класса.

Но помимо этого, это мощная конструкция, которая используется в различных языках и фреймворках, вот несколько примеров:

Я думаю, что важно отметить, что миксин не подразумевает наследование. Согласно википедии, Mixin это:

В объектно-ориентированных языках программирования миксин - это класс, который содержит методы для использования другими классами без необходимости быть родительским классом этих других классов. То, как эти другие классы получают доступ к методам миксина, зависит от языка. Миксины иногда описываются как "включенные", а не "унаследованные".

В частности, на таких языках, как perl, миксины могут быть добавлены с помощью модуля Exporter:

package Mixins;

use Exporter qw(import);
our @EXPORT_OK = qw(pity);

# assumes it will be mixed-in to a class with a _who_do_i_pity method
sub pity {
    my ($self) = @_;
    printf("I pity %s\n", $self->_who_do_i_pity('da foo'));
}

Которые могут быть добавлены к любому модулю, содержащему один или несколько методов одновременно:

package MrT

use Mixins qw(pity);

sub new {
    return bless({}, shift);
}

sub _who_do_i_pity {
    return 'da foo!'
}

Тогда в вашем MrT Модуль можно использовать таким образом:

use MrT;

MrT->new()->pity();

Я знаю, что это абсурдный пример, но он понимает суть...

ТЛ; др

mixin и множественное наследование имеют одинаковую форму. Но имеют различную семантику: mixin имеет базовые классы, обеспечивающие реализацию функции. Для наследования базовые классы предоставляют интерфейс, а подкласс имеет реализацию.

Но в любом случае, композиция предпочтительнее, чем миксин ИМО

Миксин — это класс только с методами (функциональными возможностями) и без атрибутов (данных), в то время как родительский класс в наследовании имеет как атрибуты (данные), так и методы (функциональные возможности).

При множественном наследовании новый класс может состоять из нескольких суперклассов. Вы можете вызывать только методы, определенные в любом из суперклассов.

С другой стороны, mixin - это абстрактный подкласс, который можно использовать для специализации поведения различных родительских классов. Mixins может вызывать метод (например, sayHello(): String) хотя они не определяют такой метод.

mixin M {
    name: String
    defmethod greetings() { print sayHello() + " " + name}
}

Как видите, вы можете позвонить sayHello() хотя это нигде не определено. Если вы добавите миксин M к классу C, C должен предоставить sayHello() метод.

Другие вопросы по тегам