Java 8 - interfaces with default methods against abstract classes

I am trying to answer the complete answer:

"why / when an abstract class is used, not an interface.

and is looking for confirmation / suggestions for the following.

The answer to this question is:

"to provide an implementation for some of them. Before specific classes, enter specific types, an abstract class, usually right below the interface in the inheritance hierarchy (as in many of its examples in the Java API) implements and connects some general aspects of the structure that defines interface.

Another good reason to use an abstract class is that there is a clear logical hierarchy among types. An abstract class uses a hierarchy to organize while coercion, being an abstract class, not a concrete one, creates objects only on specific classes below in this hierarchy, where they are fully defined and therefore make sense. "

Then in this context, Q appears:

"since Java 8, interfaces can define a default method . Why don't I write a default method in the interface instead of an abstract class that implements these methods?"

The answer to this question is:

"One of the reasons is that all methods of the interface are publicly available, all constants (final and public) are members of the field. You can restrict access to methods and / or make them work in an unstable state.

Another is: the descendant class can call the method of the abstract class super, while it cannot do it by default interface methods. In addition, the interface does not have constructors that will be called by descendants.

The remaining reasons are the same as in pre-Java 8 above. "

Besides the above, why do I prefer an abstract class over an interface, especially now that I have default interface methods, since Java 8?

Please note: I saw Java 8 default methods against non-abstract methods in abstract classes and Interface with default methods against an abstract class in Java 8 along with some other useful discussions. This Q is more about why I chose an abstract class by interface than vice versa.

TIA.

+5
source share
4 answers

Here are a few reasons to choose an abstract class by interface. Those that you list - private fields, etc., are one of the main ones. These are slightly more subtle.

  • Clarity of types. You can expand only one class. This gives a clearer picture of how your object uses it.
  • The problem with the diamond. You must implement all the default methods in the interface in order to avoid a diamond problem. If the interface is Collections, this can be a huge pain, as there are a billion of them. With an abstract class, you only overwrite what you need
  • Java 8 has lambda expressions, and the old interface workaround routine with the implementation method was usurped. However, when you see an interface with a standard method, this may be interpreted as you might not have expected.

Here's what Oracle has to say on this:

What should you use abstract classes or interfaces? Consider using abstract classes if any of these statements apply to your situation:

  • You want to share code between several related classes.
  • You expect classes that extend your abstract class to have many common methods or fields, or require access modifiers other than public ones (like protected and private).
  • You want to declare non-static or non-final fields. This allows you to define methods that can access and change the state of the object to which they belong.

In this article, Orace protects the distinction between the two types of systems https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

EDIT To clarify the problem with the "diamond problem" The problem is described here (and in many other places) http://www.lambdafaq.org/what-about-the-diamond-problem/

The problem arises when you inherit from two places declaring the same method, and you need to select one when allowing a function call. This was never a problem in Java 7-, since you could only extend one class and the interfaces had no methods.

Resolution tactics are now a bit complicated, but here is a good description: (from http://blog.loxal.net/2013/05/java-8-default-interface.html )

To solve the problem with diamond, there is a priority in which the implementation is used: only if the class implements all the default values ​​/ optional methods of its interfaces, the code can be compiled and implementations of this class are used. Otherwise, the compiler tries to fix missing implementations with the default implementation interface. And if there are several implementations of the default method, then there is a problem with the diamond, and the compiler rejects the compilation. Also, if the class implements the default interface of the method, the class implementation will be used instead of the default interface.

If you stick to abstract classes, you will never run into this problem. However, if your object is required to implement two interfaces (because you need to add it to lists waiting for these types, for example), and these interfaces have conflicting method signatures, you will need to redefine a whole bunch of methods, even if it means that you just make super-call calls, which defeats the dynamic inheritance sending point. This is not an end to the transaction, but something to consider when structuring a complex Java project.

+5
source

Interfaces with standard methods can define behavior, while abstract classes can have state.

In other words, you should use an abstract class if there is a member variable that needs to be shared by the subclass hierarchy (a shared resource here means that subclasses have access to it either directly if they are not private, or using methods).

Another use case for abstract classes is if you want to override some of the Object methods, such as equals or toString . This cannot be done using the default methods.

+7
source

short answer:

  • a class can distribute exactly one class.
  • a class can implement any number of interfaces.
+1
source

An abstract class has more in common with a regular class, while an interface is an open class API without an internal state.

  • An abstract class may have constructors but the interface cannot.
  • An abstract class can inherit from only one class and can implement interfaces, but an interface can extend only a few interfaces.

  • Absolute attributes may also be temporary / unstable

  • Abstract class methods can also be final / static / synchronized / native

  • Interface methods can also be default or static with implementation. (cannot be both default and static.)

0
source

Source: https://habr.com/ru/post/1206743/


All Articles