I know this question has been asked many times and we have articles all over the internet but I still cannot fully understand, when should I use interface or abstract class since I am using Java 15.
Most of the articles talk about the differences and use cases before Java 8
which makes sense but not when you can basically provide body for your methods in interface.
The only thing that made sense to me is non-public
and non-final
restrictions.
I would really appreciate if somebody can point out 1-2 examples of the scenarios where I need to choose between interface and abstract class in Java 15. Also, would be great if it can be in terms of real life projects rather than Animal or shape class examples.
Thanks !!
default
methods on interfaceApparently you are referring to the feature of “default methods” implementing behavior in an interface.
You should understand that the feature was added as a way around this dilemma: How to retroactively add features leveraging streams and lambda on existing interfaces without breaking existing classes that implement those interfaces?
Many new methods were added to those interfaces such as in the Java Collections Framework. Adding methods to an existing interface would automatically break all classes implementing the interface that are lacking the newly-required methods. Being able to provide a fallback, to give an implementation where one is now required but not yet existing, would resolve the dilemma. Thus « default methods » were born.
To quote from the Oracle tutorial linked above:
Default methods enable you to add new functionality to the interfaces of your libraries and ensure binary compatibility with code written for older versions of those interfaces.
To quote this Answer by Brian Goetz, Java Language Architect at Oracle:
The proximate reason for adding default methods to interfaces was to support interface evolution
So this feature of adding default behavior to an interface was not meant to be a new mainstream feature in and of itself. The intent of default
was not to replace abstract
.
Indeed, some experienced Java experts have recommended against making a habit of writing default methods on an interface. They recommend pretty much ignoring that feature of the Java language. Continue to think of interfaces as simply defining a contract, and abstract classes as providing partial implementations meant to be completed in a subclass.
You are certainly free to write your own default methods on your interfaces. And certainly you should do so if you are in a similar situation of having published an interface that others may have implemented, and now you want to add methods. But unnecessarily adding default methods is likely to confuse other programmers who expect partial implementations on an abstract class rather than an interface.
default
method on an interfaceIn that same post linked above, Brian Goetz suggests three other cases beyond interface evolution where default methods on an interface may be appropriate. Here is a quick mention; see his post for details.
default
method throws an UnsupportedOperationException
because we expect implementations of this interface to more often not want to implement this method.As for choosing between an interface and abstract class:
default
method. Consider if your situation meets one of the four cases recommended by Brian Goetz as discussed above.For example, you might have a class for domestic ShippingLabelUS
as well as ShippingLabelCanada
and ShippingLabelOverseas
. All three need to convert between imperial pounds and metric kilograms. You find yourself copying that code between the classes. At this point you might consider having all three classes extend from abstract class ShippingLabel
where a single copy of the weight conversion methods live.
While designing your API keep in mind that Java, like most OOP languages, has single-inheritance. So your subclasses are limited to extending only one class. To be a bit more specific about the single-versus-multiple inheritance, I will quote Brian Goetz from this PDF of a slide deck:
[regarding
default
methods on an interface]Wait,is this multiple inheritance in Java?
• Java always had multiple inheritance of types
• This adds multiple inheritance of behavior
• But not of state, where most of the trouble comes from
An alternative to using an abstract class for shared behavior is creating a separate class for specific behavior, then adding an object of that separate class to be kept as a member field on the larger class. Wise programmers often share this pearl of wisdom: Prefer composition over inheritance.
Regarding the shipping label example above, you could create a WeightConverter
class, an object of which would be a member of each of the three label classes. In this arrangement, no need for the abstract class.