A Mixin is a set of properties and methods that can be used in different classes, which don't come from a base class. In Object Oriented Programming languages, you typically use inheritance to give objects of different classes the same functionality; if a set of objects have some ability, you put that ability in a base class that both objects inherit from.
For instance, say you have the classes
Plane. Objects from all of these classes have the ability to travel, so they get the function
travel. In this scenario, they all travel the same basic way, too; by getting a route, and moving along it. To implement this function, you could derive all of the classes from
Vehicle, and put the function in that shared class:
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): ...
With this code, you can call
travelon a car (
car.travel("Montana")), boat (
boat.travel("Hawaii")), and plane (
However, what if you have functionality that's not available to a base class? Say, for instance, you want to give
Car a radio and the ability to use it to play a song on a radio station, with
play_song_on_station, but you also have a
Clock that can use a radio too.
Clock could share a base class (
Machine). However, not all machines can play songs;
Plane can't (at least in this example). So how do you accomplish without duplicating code? You can use a mixin. In Python, giving a class a mixin is as simple as adding it to the list of subclasses, like this
class Foo(main_super, mixin): ...
Foo will inherit all of the properties and methods of
main_super, but also those of
mixin as well.
So, to give the classes
Carand clock the ability to use a radio, you could override
Carfrom the last example and write this:
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): ...
Now you can call
clock.play_song_on_station(101.3), but not something like
The important thing with mixins is that they allow you to add functionality to much different objects, that don't share a "main" subclass with this functionality but still share the code for it nonetheless. Without mixins, doing something like the above example would be much harder, and/or might require some repetition.