Does Java have plan that default method
substitute for Abstract Class
?
I could not find a real case to use default method instead of Abstract?
Default methods can't substitute abstract classes, as abstract classes can (and often do) have fields. Interfaces can only contain behaviour and not state, which is unlikely to change in the future as multiple inheritance of state in Java is seen (rightly or wrongly) as evil.
They can also have final
methods, which is another thing you can't mimic with default
methods.
If anything, interfaces with default methods resemble traits rather than abstract classes, but the match isn't perfect. Using interfaces as traits is something that has to be done very carefully and knowing the limitations they come with. (Such as any implementing class can override a default
method, potentially ruining the trait.)
private
methods in interfaces only help sharing code between different always-public
default
or static
methods. That’s different from publishing methods with access control, i.e. declare them protected
or package-private. Note that the support for private
methods in interfaces is already de-facto in Java 8, as lambda expressions get compiled into private
methods, this also holds for lambda expressions contained in default
or static
interface methods. –
Laddie There are no such plans, which you can derive from comparing the already documented intentions, which differ from the implications of such a plan:
The main goal is to allow interface evolution, that is, the addition of new methods. If a new method is added to an interface, existing classes that implement the interface would be missing an implementation, which would be incompatible. To be compatible, an implementation has to come from somewhere, so it is provided by default methods.
…
The main intent of a Java interface is to specify a contract that any class can implement without having to alter its position in the class hierarchy. It's true that, prior to Java 8, interfaces were purely abstract. However, this is not an essential property of interfaces. Even when default methods are included, an interface at its heart still specifies a contract upon the implementing class. The implementing class can override default methods, so the class is still in complete control of its implementation. (Note also that default methods cannot be final.)
and Brian Goetz writes:
The proximate reason for adding default methods to interfaces was to support interface evolution, …
Here are some use cases that are well within the design goals:
Interface evolution. Here, we are adding a new method to an existing interface, which has a sensible default implementation in terms of existing methods on that interface. An example would be adding the
forEach
method toCollection
, where the default implementation is written in terms of theiterator()
method."Optional" methods. Here, the designer of an interface is saying "Implementors need not implement this method if they are willing to live with the limitations in functionality that entails". For example,
Iterator.remove
was given a default which throwsUnsupportedOperationException
; since the vast majority of implementations ofIterator
have this behavior anyway, the default makes this method essentially optional. (If the behavior fromAbstractCollection
were expressed as defaults onCollection
, we might do the same for the mutative methods.)Convenience methods. These are methods that are strictly for convenience, again generally implemented in terms of non-default methods on the class. The
logger()
method in your first example is a reasonable illustration of this.Combinators. These are compositional methods that instantiate new instances of the interface based on the current instance. For example, the methods
Predicate.and()
orComparator.thenComparing()
are examples of combinators.
Note that these do not target the primary domain of abstract classes, like providing a skeleton implementation. Besides the technical differences, abstract classes are semantically different as they bear design decisions about how to implement the functionality, which interfaces, even with default
methods, should not. E.g. a well-known example is the List
interface, for which two fundamentally different abstract classes exist, AbstractList
and AbstractSequentialList
and the choice of subclasses either or implementing List
entirely different should not be foreclosed by the interface. So the List
interface defines the contract and can never be a substitute for an abstract class, which provides a particular base implementation.
default
methods which are actually unusable, without a chance for the client code to find out. The task of finding the implementation is as easy as clicking on the method in an IDE, not that it matters as you should develop against the contract, regardless of where the method is implemented, and the “diamond inheritance” isn’t an actual problem as the language forbids ambiguous inheritance. And while interface evolution is an important goal it is not the only goal. Consider this… –
Laddie Other answers, and links to additional materials, have already adequately covered the technical differences between interfaces and abstract classes. What hasn't been covered well is why to use one over the other.
Consider two different ways to use a class or interface in Java: as a caller or as a subclasser. A caller has an object reference and can call public
methods and access public
fields via that reference. A subclasser can also access, call, and override protected
members of the superclass. Classes can have protected
members, but interfaces cannot.
A common question seems to be, now that we have default methods, why do we need abstract classes? A default method is part of what the interface presents to callers. A protected
method on a class is not available to callers; it is only available to subclassers. Thus, if you want to share implementation with subclassers, then use a class (or abstract class) and define protected
members and fields.
The protected
mechanism allows a class to communicate with subclassers, distinct from the way it communicates with callers.
But the OP asks the opposite question: why would one use default methods in preference to abstract classes? In the situation where you actually have a choice (i.e., your abstraction doesn't require state, or protected methods, or any of the things that abstract classes have that interfaces do not), interfaces with default methods are far less constraining than abstract classes. You can only inherit from one class; you can inherit from many interfaces. So interfaces with default methods can behave like stateless traits or mixins, allowing you to inherit behavior from multiple interfaces.
Given that interfaces and abstract classes are used for different purposes, there is no plan to remove or replace anything.
One of the reasons why default methods in interfaces were introduced was to allow adding new methods to the JDK interfaces.
Without this feature once a class has been compiled with a specific version of an interface no new methods can be added to this interface. With the default methods in interfaces feature interfaces can be changed.
Default methods can't substitute abstract classes, as abstract classes can (and often do) have fields. Interfaces can only contain behaviour and not state, which is unlikely to change in the future as multiple inheritance of state in Java is seen (rightly or wrongly) as evil.
They can also have final
methods, which is another thing you can't mimic with default
methods.
If anything, interfaces with default methods resemble traits rather than abstract classes, but the match isn't perfect. Using interfaces as traits is something that has to be done very carefully and knowing the limitations they come with. (Such as any implementing class can override a default
method, potentially ruining the trait.)
private
methods in interfaces only help sharing code between different always-public
default
or static
methods. That’s different from publishing methods with access control, i.e. declare them protected
or package-private. Note that the support for private
methods in interfaces is already de-facto in Java 8, as lambda expressions get compiled into private
methods, this also holds for lambda expressions contained in default
or static
interface methods. –
Laddie © 2022 - 2024 — McMap. All rights reserved.