3 Mixin

Mixin представляет собой набор свойств и методов , которые могут быть использованы в различных классах, которые не приходят из базового класса. В объектно - ориентированных языках программирования, вы , как правило , использовать наследование , чтобы дать объекты различных классов ту же функциональность; если множество объектов есть некоторые способности, вы помещаете эту способность в базовом классе , что оба объекта унаследованы из.

Например, у вас есть классы Car , Boat и Plane . Объекты из всех этих классов имеют возможность путешествовать, так что они получают функцию travel . В этом сценарии все они тоже путешествуют одинаково; получая маршрут и двигаясь по нему. Для реализации этой функции, вы можете получить все классы от Vehicle , и поставить функцию в этом разделяемой классе:

 class Vehicle(object):
   """A generic vehicle class."""

   def __init__(self, position):
       self.position = position

   def travel(self, destination):
       route = calculate_route(from=self.position, to=destination)
       self.move_along(route)

class Car(Vehicle):
   ...

class Boat(Vehicle):
   ...

class Plane(Vehicle):
   ... 

С помощью этого кода, вы можете позвонить в travel на автомобиле ( car.travel("Montana") ), лодки ( boat.travel("Hawaii") ), и плоскость ( plane.travel("France") )

Однако что если у вас есть функциональность, недоступная базовому классу? Скажем, к примеру, вы хотите , чтобы Car радио и возможность использовать его , чтобы играть песню на радиостанции, с play_song_on_station , но у вас также есть Clock , которые могут использовать радио тоже. Car и Clock могут совместно использовать базовый класс ( Machine ). Однако не все машины могут воспроизводить песни; Boat и Plane не может ( по крайней мере , в данном примере). Так как же добиться успеха без дублирования кода? Вы можете использовать миксин. В Python дать классу mixin так же просто, как добавить его в список подклассов, как это

 class Foo(main_super, mixin): ... 

Foo наследует все свойства и методы main_super , но и те из mixin , а также.

Таким образом, чтобы дать классы для Car и Часовой возможность использовать радио, вы можете переопределить Car из предыдущего примера и написать это:

 class RadioUserMixin(object):
   def __init__(self):
       self.radio = Radio()

   def play_song_on_station(self, station):
       self.radio.set_station(station)
       self.radio.play_song()

class Car(Vehicle, RadioUserMixin):
   ...

class Clock(Vehicle, RadioUserMixin):
   ... 

Теперь вы можете вызвать car.play_song_on_station(98.7) и clock.play_song_on_station(101.3) , но не что - то вроде boat.play_song_on_station(100.5)

С миксинами важно то, что они позволяют вам добавлять функциональные возможности к разным объектам, которые не разделяют «основной» подкласс с этой функциональностью, но, тем не менее, совместно используют код для него. Без миксинов сделать что-то похожее на приведенный выше пример будет гораздо сложнее и / или может потребоваться некоторое повторение.