So, Java 8 was released just weeks ago, and one of the features that immediatelly caught my attention was Default Interface Implementation, which is, you can give a method of an Interface a default body (similar to a concrete method in an abstract class).
Why did it caught my attention? Because, at first sight, it goes against the principle behind the creation of Interfaces!!!
I started in programming with C++, and in that language a class can inherit multiple classes (multiple inheritance). And that has a problem: the Diamond Problem.
The Diamond Problem
Imagine there are classes VideoGameConsole and DVDPlayer. Both inherit from the abstract class EletronicDevice. Now, a new video game was just released and it has both video game and dvd player functionalities (old story, but...)! Remembering that C++ does not have interfaces, so we can declare PS3Console as inheriting VideoGameConsole and DVDPlayer. Like this:
Now, EletronicDevice has an abstract method called getPowerSupplyVoltage(). As VideoGameConsole and DVDPlayer are concrete, both have implementations of this method. And if we do not override this method in the PS3Console, what will happen when we try to call it from an object of PS3Console class?
There can be other methods that fall into the same problem in this cenario: maybe isReadyForUse(), turnOn(), turnOff(), hasScreen(), getModel(), etc.
Many programming languages have ways to mitigate this problems. You can see some on Wikipedia's page on multiple inheritance.
The Java Way
Java uses Interfaces and Single Inheritance rule to eliminate the Diamond Problem. When a class can inherit only one other class, there is no cenario that can lead to the problem, and by adding Interface types (which can inherit multiple interfaces), the programmer can still add functionality (with polymorphism and inheritance features) to classes.
Also, in my opinion, when you structure classes by being super strict on validating inheritance, and adding functionality with Interfaces, the structure becomes more clear. Let me explain: for me, it's weird to say a PS3Console is a (IS-A) DVDPlayer. A inheritance express specialization, and a PS3 is not a specialized DVD player (and the reverse is not true either). In Java way of design, probably, PS3Console would inherit EletronicDevice directly.
What about polymorphism? I would create interfaces like CanPlayDVDs and CanPlayGames (maybe with better names :D).
What about code reuse? IF (and only if) I needed to reuse the implementation of those interface methods, I would use the Strategy Design Pattern (defined in this book by Gamma et al), which is (simplifying a bit) composition with polimorphism.
Ok, back to Java 8 release: Interfaces now can have implementations of their methods (!!!). This was done to allow evolution of published Interfaces without breaking code, according to this overview, and together with static interface method implementations, to allow generic functionality to be provided without an auxiliary class (like java.util.Collections class is for java.util.Collection interface).
Right, what about the Diamond Problem? The compiler checks for it and issues a compiler error. Then what? Well..... if I'm right, you'll have to change the structure of your class relationships OR implement that method and discard all default implementations.
I dislike this feature. I think it can cause design confusion, and the only advantage is to advance APIs that must have backward compatibility. But I'm very glad that they defined that the Diamond Problem must be identified in compiling time - this will avoid a lot of problems.
Any thoughts about this new feature? Leave a comment below. ;)