Міксин проти спадкування


Відповіді:


66

Міксин, як правило, використовується з багаторазовим успадкуванням. Отже, в цьому сенсі "різниці немає".

Подробиця полягає в тому, що міксин рідко корисний як окремий об'єкт.

Наприклад, скажімо, у вас є мікс з назвою "ColorAndDimension", який додає властивості кольору та ширини та висоти.

Тепер ви можете додати ColorAndDimension до, скажімо, класу Shape, класу Sprite, класу Car та ін. І всі вони матимуть однаковий інтерфейс (скажімо, get / setColor, get / setHeight / Width тощо)

Так, у родовому випадку спадщина mixin IS. Але ви можете стверджувати, що це питання класу в загальній галузі, чи є mixin "первинним" класом чи просто mixin.


Редагувати - просто для уточнення.

Так, міксин може вважатися в сучасній сучасній мові інтерфейсом із пов'язаною реалізацією. Це дійсно просто звичайне, старе, щоденне багаторазове успадкування, використовуючи звичайний, старий, повсякденний клас. Просто трапляється конкретне застосування ІМ. Більшість мов не надають міксину особливого статусу; це просто клас, який був розроблений так, щоб він був "змішаним", а не використовувався окремо.


29

Яка різниця між міксином та спадщиною?

Суміш в базовий клас ви можете успадковувати від надання додаткової функціональності. Приклад псевдокоду:

class Mixin:
    def complex_method(self):
        return complex_functionality(self)

Назва "суміш" вказує, що вона призначена для змішування з іншим кодом. Таким чином, висновок полягає в тому, що ви не могли б самостійно інстанціювати мікс-клас. У наступного об'єкта немає даних, і немає сенсу придумувати його викликати комплекс_метод. (У цьому випадку ви можете просто визначити функцію замість класу.)

>>> obj = Mixin()

Часто суміш використовується з іншими базовими класами.

Тому міксини - це підмножина, або окремий випадок спадкування.

Переваги використання суміші над одним успадкуванням полягають у тому, що ви можете написати код для функціональності одноразово, а потім використовувати ту саму функціональність у кількох різних класах. Недоліком є ​​те, що вам може знадобитися шукати цю функціональність в інших місцях, ніж там, де вона використовується, тому добре пом'якшити цей недолік, тримаючи його поруч.

Я особисто знайшов суміш, необхідний для використання над одним успадкуванням, коли ми випробовуємо багато подібного коду, але тестові випадки створюються миттєво на основі їх успадкування базового випадку, і єдиний спосіб тримати код близьким сторона (і в тому ж модулі), не возившись з номерами покриття, має успадковувати об'єкт, а дочірні випадки успадковувати як універсальну базу тестових випадків, так і користувацьку базу, яка стосується лише їх.

Міксини в порівнянні та контрасті з абстрактними базовими класами

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

Mixin забезпечує функціональні можливості , але не може безпосередньо використовувати його. Користувач має намір використовувати його через (під) клас.

Абстрактний базовий клас надає інтерфейс, але без корисної функціональності. Користувач призначений для створення функціональних можливостей, викликаних інтерфейсом.

class Abstraction(metaclass=abc.ABCMeta):
    @abc.abstractmethod
    def complex_method(self):
        return complex_functionality(self)

Тут вам заборонено створювати цей об'єкт, оскільки він вимагає підкласу для реалізації функціональності конкретним методом (хоча ви можете отримати доступ до функціоналу зсередини super()):

>>> obj = Abstraction()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Abstraction with
abstract methods complex_method

У Python деякі класи abcмодуля є прикладами батьківських класів, які забезпечують функціональність через успадкування та абстрактні інтерфейси, які повинні бути реалізовані підкласом. Ці ідеї не є взаємовиключними.

Підсумок

Простіше кажучи, суміш - це лише базовий клас, який ви не використовували б самостійно, і зазвичай використовується як вторинний базовий клас при багатократному успадкуванні.


18

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


7

Mixin - це абстрактне поняття, і все, що відповідає його вимогам, може розглядатися як міксин.

Ось визначення з Вікіпедії.

У об'єктно-орієнтованих мовах програмування mixin - це клас, який містить методи для використання іншими класами, не будучи батьківським класом цих інших класів. Як інші класи отримують доступ до методів Mixin, залежить від мови. Міксини іноді описують як "включені", а не "успадковані".

Коротше кажучи, ключова відмінність від спадщини полягає в тому, що сумішам НЕ потрібно мати відносини "є-а", як у спадщині.

З точки зору реалізації, ви можете вважати це інтерфейсом з реалізаціями. Наприклад, абстрактний клас на Java може розглядатися як міксин, якщо Java підтримує багатократне успадкування.


Мені важко зрозуміти сміливе речення. Це звучить як "відмінність (B?) Від A полягає в тому, що йому (B?) Потрібно щось подібне в A". Ви говорите про різницю чи схожість?
RayLuo

@RayLuo Whoops ... Я зробив кілька помилок. Вибачте, що вас заплутали. З міксами НЕ потрібно мати стосунки "є-а"
Олексій

3

"Міксин - це фрагмент класу в тому сенсі, який він повинен бути складений з іншими класами або міксинами." -DDJ

Mixin - це фрагмент класу або коду, який не призначений для самостійного використання, але замість цього ви повинні використовувати його всередині іншого класу. Або складати його як поле члена / змінну або як сегмент коду. У мене найбільше впливає на пізніші. Це трохи краще, ніж копіювальний код котла.

Ось чудова стаття DDJ, яка знайомить із темою.

Half-Life 2 / "Джерело" SDK - чудовий приклад змісту C ++. У цьому середовищі макроси визначають значні блоки коду, які можна додати, щоб надати класу певний "аромат" чи особливість.

Подивіться приклад вікі джерела: Автор логічної сутності . У прикладі коду макрос DECLARE_CLASS можна вважати міксином. Джерело SDK широко використовує mixins для стандартизації коду доступу до даних та приписування поведінки суб'єктам.


0

При багатократному успадкуванні новий клас може складатися з декількох суперкласів. Ви можете зателефонувати лише до методів, визначених у будь-якому з суперкласів.

З іншого боку, mixin - це абстрактний підклас, який може використовуватися для спеціалізації поведінки різних батьківських класів. Міксини можуть викликати метод (наприклад sayHello(): String), навіть якщо такий метод не визначає.

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

Як бачите, ви можете зателефонувати, sayHello()навіть якщо це ніде не визначено. Якщо ви додаєте міксин Mдо класу C, метод Cповинен надати sayHello()метод.


1
не впевнений у правильності вашого першого твердження - класи можуть визначати власні методи
EugeneMi

0

Я думаю, що важливо зазначити, що міксин не означає спадкування . Згідно з Вікіпедією, Міксин - це:

У об'єктно-орієнтованих мовах програмування mixin - це клас, який містить методи для використання іншими класами, не будучи батьківським класом цих інших класів. Як інші класи отримують доступ до методів Mixin, залежить від мови. Міксини іноді описують як "включені", а не "успадковані".

Зокрема, такою мовою, як perl, міксини можна додавати за допомогою модуля експортера:

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();

Я знаю, що це абсурдний приклад, але це стає зрозумілим ...


0

тл; д-р

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

Але так чи інакше, композиція є кращою перед Mixin IMO

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.