In The new Java 8 Date and Time API: An interview with Stephen Colebourne, Stephen Colebourne tells Hartmut Schlosser, "I think the most important language change isn't lambdas, but static and default methods on interfaces." Colebourne adds, "The addition of default methods removes many of the reasons to use abstract classes." As I read this, I realized that Colebourne is correct and that many situations in which I currently use abstract classes could be replaced with interfaces with JDK 8 default methods. This is pretty significant in the Java world as the difference between abstract classes and interfaces has been one of the issues that vex new Java developers trying to understand the difference. In many ways, differentiating between the two is even more difficult in JDK 8.
There are numerous examples of online forums and blogs discussing the differences between interfaces and abstract classes in Java. These include, but are not limited to, JavaWorld's Abstract classes vs. interfaces, StackOverflow's When do I have to use interfaces instead of abstract classes?, Difference Between Interface and Abstract Class, 10 Abstract Class and Interface Interview Questions Answers in Java, As useful and informative as these once were, many of them are now outdated and may be part of even more confusion for those new to Java who start their Java experience with JDK 8.
As I was thinking about the remaining differences between Java interfaces and abstract classes in a JDK 8 world, I decided to see what the Java Tutorial had to say on this. The tutorial has been updated to reflect JDK 8 and the Abstract Methods and Classes has a section called "Abstract Classes Compared to Interfaces" that has been updated to incorporate JDK 8. This section points out the similarities and differences of JDK 8 interfaces with abstract classes. The differences it highlights are the accessibility of data members and methods: abstract classes allow non-static and non-final fields and allow methods to be public, private, or protected while interfaces' fields are inherently public, static, and final, and all interface methods are inherently public.
The Java Tutorial goes on to list bullets for when an abstract class should be considered and for when an interface should be considered. Unsurprisingly, these are derived from the previously mentioned differences and have primarily to do with whether you need fields and methods to be private, protected, non-static, or not final (favor abstract class) or whether you need the ability to focus on typing without regard to implementation (favor interface).
Because Java allows a class to implement multiple interfaces but extend only one class, the interface might be considered advantageous when a particular implementation needs to be associated with multiple types. Thanks to the JDK 8's default methods, these interfaces can even provide default behavior for implementations.
A natural question might be, "How does Java handle a class that implements two interfaces, both of which describe a default method with the same signature?" The answer is that this is a compilation error. This is shown in the next screen snapshot which shows NetBeans 8 reporting the error when my class implemented two interfaces that each defined a default method with the same signature [String speak()
].
As the screen snapshot above indicates, a compiler error is shown that states, "class ... inherits unrelated defaults for ... from types ... and ..." (where the class name, defaults method name, and two interface names are whatever are specified in the message). Peter Verhas has written a detailed post ("Java 8 default methods: what can and can not do?") looking at some corner cases (gotchas) related to multiply implemented interfaces with default method names with the same signature.
ConclusionJDK 8 brings arguably the abstract class's greatest advantage over the interface to the interface. The implication of this is that a large number of abstract classes used today can likely be replaced by interfaces with default methods and a large number of future constructs that would have been abstract classes will now instead be interfaces with default methods.
1 comment:
Stuart Marks has posted the insightful "Incompatibilities with JDK 15 CharSequence.isEmpty" that provides in-depth analysis of how "adding a default method to an interface is potentially both a source and binary incompatible change."
Post a Comment