I'm trying to come up with a complete answer to:
"why/when use an abstract class rather than an interface."
and looking for verification/suggestions on the following.
An answer to this is,
"to provide the implementation for some of it. Before the concrete classes come in to define the specific types, an abstract class, typically right below an interface in the inheritance hierarchy (as in many of its examples in the Java APIs) implements and pins down some common aspects of the structure that interface defines.
Another good reason to use an abstract class is that there is a clear logical hierarchy among the types. Abstract class has the use to organize that hierarchy while forcing, by being an abstract class rather than a concrete one, the instantiation of objects only on the concrete classes down below in this hierarchy where they are fully defined and thus are meaningful."
Then, in this context, comes the Q:
"since Java 8, interfaces can define default method implementations. Why wouldn't i write default method(s) in the interface instead of an abstract class that implements those method(s)? "
The answer to this would be:
" One reason is: interface methods are all public, field members are all constants (final & public). You may wanna restrict access privileges of methods and/or make them operate on non-constant state.
Another is: a descendant class can call upon the abstract class method(s) by super, while it can not do so on default interface methods. Also, the interface has no constructors to be invoked by the descendants.
The rest of the reasons are the same as those in pre-Java 8 above. "
Other than these above, why would i rather go for an abstract class than an interface especially now that i have the default interface methods since Java 8?
Please note: i've seen Java 8 default methods vs. non-abstract methods in abstract classes and Interface with default methods vs Abstract class in Java 8 along with some other useful discussions. This Q is rather about why chose an abstract class over an interface than the other way round.
TIA.
Here are some reasons to choose an abstract class over an interface. The ones you list - private fields, etc., are some of the major ones. These are a few more subtle ones
Here's what Oracle has to say on the subject:
In this article, Orace defends the distinction between the two type systems https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
EDIT To clarify the "diamond problem" bullet The problem is described here (and many other places) http://www.lambdafaq.org/what-about-the-diamond-problem/
The problem occurs when you inherit from two places that declare the same method, and you have to pick one when resolving a function call. This was never an issue in Java 7-, since you could only extend one class and interfaces had no methods.
The resolution tactic now is a little complicated, but here is a good description of it: (from http://blog.loxal.net/2013/05/java-8-default-interface.html)
If you stick to abstract classes, you will never run into this problem. However, if your object is required to implement two interfaces (because it needs to be added to lists that are expecting those types, e.g.), and those interfaces have conflicting method signatures, you will wind up having to redefine a whole bunch of methods even if that means you're just making super calls, which sort of defeats the point of inheritance-based dynamic dispatch. It isn't a deal-breaker, but something to consider when structuring a complex Java project
short answer:
Abstract class shares more similarities with a normal class whereas interface represents the class public API with no internal state.
Abstract class can inherit from only one class and can implement interfaces but an interface can only extend multiple interfaces.
Abstract class attributes can also be transient/volatile
Abstract class methods can also be final/static/synchronized/native
Interface methods can also be default or static with the implementation.( cannot be both default and static. )
Interfaces with default methods can only define behaviour whereas abstract classes can have a state.
In other words you should use an abstract class if there is a member variable that you need to share across a subclass hierarchy (share here means that subclasses have access to it either directly if it is not private or through methods).
Another use case of abstract classes is if you want to override some of the
Object
methods such asequals
ortoString
. That can't be done through default methods.