Starting in Android N Google has added some java 8 language features. One of those features is the ability to add default methods to interfaces. Surprisingly (since java 8 has already been released 2 years ago) I haven’t found good articles describing the advantage of default methods for interfaces: Mixins!
Let’s straight jump into a simple example. Let’s say we have a class Ship. A Ship can carry Cargo. Let’s model that in Java like this:
We also have an Airport where Aircrafts can land and depart:
Given that, what if we want to have another class that is Airport and Ship at the same time? Unrealistic? What about an AircraftCarrier. Since java doesn’t support multiple inheritance we can’t declare a class AircraftCarrier that extends from Airport and Ship:
So what alternatives do we have to make AircraftCarrier be a Ship and a Airport at the same time? Well, we could use delegation (“favor composition over inheritance”) or some tricks from aspect orientated programming, but none of them are really natively supported by java programming language.
However, java does support multiple inheritance on interfaces and allows classes to implement arbitrary many interfaces. So let’s convert Ship and Airport to interfaces:
But now we have to implement the methods from each interface manually. Not a big deal in this simple example because it’s basically just one line of code for each method but I guess you get the point.
How does Ruby programmers deal with inheritance? Experienced Ruby programmers don’t use inheritance for such things. They use Mixins:
With Mixins we can compose AircraftCarrier by “including” (or mixing in) the functionality of Ship and Airport without inheritance. Ship definition has been omitted for better readability but I guess you can imagine how the code for module Ship will look like. Please note that this is not multiple inheritance as C++ offers (diamond problem). Mixins are a different concept. The Ruby programming language has native support for Mixins. What about other languages like Scala? Scala has support for Mixins as well. In Scala those are called Traits. Traits are Mixins just with some slightly different properties from a programming language designers point of view like Mixins require linearization while Traits are flattened and Traits traditionally don’t contain states. But that shouldn’t worry you too much. For the sake of simplicity we can say Mixins and Traits are the same.
And then with Scala we can do something like this:
See the thing is both, Ruby and Scala, natively have language support for Mixins. But what about java? With Java 8 and default methods for interfaces we can do pretty the same thing:
We will do the same for Ship (interface with default method implementations) and then we can do something like this:
Moreover, now we can compose new classes even more easily and without traditional inheritance:
I guess you get the point. With Java 8 and default methods for interfaces we can use Mixins instead of inheritance. kotlin also offers Mixins via interfaces with default methods:
Hopefully you see that Mixins may be a better choice than traditional inheritance. But how does that help in android development. In android we always have to extend from Activity or Fragment, which are obviously two different base classes. With Mixins, we can share code between both classes that extends from Activity and classes that extends from Fragment. Sure this is not the main use case of Mixins (delegation might be a better choice) because those methods defined in the Mixin will be used internally from the Fragment or Activity himself which are implementing the Mixin interface, but it is a valid option though. Unfortunately, interfaces with default methods on Android requires min sdk 24 (Android N) and Jack as compiler.
See the moral of the story is it is good to have an alternative to inheritance and I have the feeling that unfortunately Mixins via interfaces with default implementation are not used that much in the java world.
My general advice about inheritance:
Inheritance doesn’t scale well! Use inheritance for inheriting properties but not for inheriting functionality! Mixins are better suited for “inheriting” functionality.