A mixin is a type which can be mixed in to (i.e. included in) other types via multiple inheritance. This allows the encapsulation of certain behaviors which cut across the main type hierarchy. In C++ this is fairly standard, though it’s sometimes discouraged because of the potential for the “diamond problem”. In Java 8, mixins can be created using interfaces with default methods.
Why use mixins in Java?
Mixins give you design options which you did not have before. A class can inherit behavior that isn’t in its superclass. For example, you can have Goose implements Honker and Car implements Honker – with no need to implement honk() more than once. Some more practical uses include test fixtures (which I will address in more detail in my next article), and logging.
Default methods in mixins are also very useful for wrapping static method calls, especially in legacy code. This is what my interface-it tool automates. So you can replace static calls with calls to interface methods that can be mocked in tests, and/or overridden for special cases. It allows you to make a procedural design more object-oriented and pull hidden dependencies out into the open. It also lets you avoid using static imports, which can make the code less readable.
Finally, a benefit of mixins is polymorphism. You can override or extend the default behavior in special cases, which is something you can’t do with static calls.