Default Interface Methods. What Is Deep Meaningful Difference Now, Between Abstract Class and Interface

Default Interface Methods. What is deep meaningful difference now, between abstract class and interface?

There is not a lot of difference between the two apart from the obvious fact that abstract classes can have state and interfaces cannot. Default methods or also known as virtual extension methods have actually been available in Java for a while. The main drive for default methods is interface evolution which means being able to add methods to an interface in future versions without breaking source or binary compatibility with existing implementations of that interface.

another couple of good points mentioned by this post:

  • The feature enables C# to interoperate with APIs targeting Android
    (Java) and iOs (Swift), which support similar features.
  • As it turns out, adding default interface implementations provides
    the elements of the "traits" language feature
    (https://en.wikipedia.org/wiki/Trait_(computer_programming)). Traits
    have proven to be a powerful programming technique
    (http://scg.unibe.ch/archive/papers/Scha03aTraits.pdf).

What is the difference between an interface and abstract class?

Interfaces

An interface is a contract: The person writing the interface says, "hey, I accept things looking that way", and the person using the interface says "OK, the class I write looks that way".

An interface is an empty shell. There are only the signatures of the methods, which implies that the methods do not have a body. The interface can't do anything. It's just a pattern.

For example (pseudo code):

// I say all motor vehicles should look like this:
interface MotorVehicle
{
void run();

int getFuel();
}

// My team mate complies and writes vehicle looking that way
class Car implements MotorVehicle
{

int fuel;

void run()
{
print("Wrroooooooom");
}

int getFuel()
{
return this.fuel;
}
}

Implementing an interface consumes very little CPU, because it's not a class, just a bunch of names, and therefore there isn't any expensive look-up to do. It's great when it matters, such as in embedded devices.


Abstract classes

Abstract classes, unlike interfaces, are classes. They are more expensive to use, because there is a look-up to do when you inherit from them.

Abstract classes look a lot like interfaces, but they have something more: You can define a behavior for them. It's more about a person saying, "these classes should look like that, and they have that in common, so fill in the blanks!".

For example:

// I say all motor vehicles should look like this:
abstract class MotorVehicle
{

int fuel;

// They ALL have fuel, so lets implement this for everybody.
int getFuel()
{
return this.fuel;
}

// That can be very different, force them to provide their
// own implementation.
abstract void run();
}

// My teammate complies and writes vehicle looking that way
class Car extends MotorVehicle
{
void run()
{
print("Wrroooooooom");
}
}

Implementation

While abstract classes and interfaces are supposed to be different concepts, the implementations make that statement sometimes untrue. Sometimes, they are not even what you think they are.

In Java, this rule is strongly enforced, while in PHP, interfaces are abstract classes with no method declared.

In Python, abstract classes are more a programming trick you can get from the ABC module and is actually using metaclasses, and therefore classes. And interfaces are more related to duck typing in this language and it's a mix between conventions and special methods that call descriptors (the __method__ methods).

As usual with programming, there is theory, practice, and practice in another language :-)

When to use: Java 8+ interface default method, vs. abstract method

There's a lot more to abstract classes than default method implementations (such as private state), but as of Java 8, whenever you have the choice of either, you should go with the defender (aka. default) method in the interface.

The constraint on the default method is that it can be implemented only in the terms of calls to other interface methods, with no reference to a particular implementation's state. So the main use case is higher-level and convenience methods.

The good thing about this new feature is that, where before you were forced to use an abstract class for the convenience methods, thus constraining the implementor to single inheritance, now you can have a really clean design with just the interface and a minimum of implementation effort forced on the programmer.

The original motivation to introduce default methods to Java 8 was the desire to extend the Collections Framework interfaces with lambda-oriented methods without breaking any existing implementations. Although this is more relevant to the authors of public libraries, you may find the same feature useful in your project as well. You've got one centralized place where to add new convenience and you don't have to rely on how the rest of the type hierarchy looks.

What are the differences between abstract classes and interfaces in Java 8?

Interfaces cannot have state associated with them.

Abstract classes can have state associated with them.

Furthermore, default methods in interfaces need not be implemented. So in this way, it will not break already existing code, as while the interface does receive an update, the implementing class does not need to implement it.

As a result you may get suboptimal code, but if you want to have more optimal code, then your job is to override the default implementation.

And lastly, in case a diamond problem occurs, then the compiler will warn you, and you will need to choose which interface you want to implement.

To show more about the diamond problem, consider the following code:

interface A {
void method();
}

interface B extends A {
@Override
default void method() {
System.out.println("B");
}
}

interface C extends A {
@Override
default void method() {
System.out.println("C");
}
}

interface D extends B, C {

}

Here I get the compiler error on interface D extends B, C, that:

interface D inherits unrelated defaults for method() form types B and C

The fix is:

interface D extends B, C {
@Override
default void method() {
B.super.method();
}
}

In case I wanted to inherit the method() from B.

The same holds for if D were a class.

To show even more about the difference between interfaces and abstract classes in Java 8, consider the following Team:

interface Player {

}

interface Team {
void addPlayer(Player player);
}

You can in theory provide a default implementation of addPlayer such that you can add players to for example a list of players.

But wait...?

How do I store the list of players?

The answer is that you cannot do that in an interface, even if you have default implementations available.

Java 8 -- interfaces with default methods vs abstract classes

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

  • Type clarity. You can only extend one class. This makes it clearer what your object is an how to use it.
  • The diamond problem. You have to implement all of the default methods in an interface to help avoid the diamond problem. If the interface is Collections, this can be a huge pain since there are a billion of them. With an abstract class, you only overwrite what you need to
  • In Java 8, there are lambda expressions, and the old routine of passing around an interface with a method to implement has been usurped. Still, when you see an interface with a default method, this can interpreted in ways you might not intend

Here's what Oracle has to say on the subject:

Which 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 among several closely related classes.
  • You expect that classes that extend your abstract class have many common methods or fields, or require access modifiers other than
    public (such as protected and private).
  • You want to declare non-static or non-final fields. This enables you to define methods that can access and modify the state of the
    object to which they belong.

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)

To address the diamond problem there is a precedence in which order an
implementation is used: only if the class implements all default /
optional methods of its interfaces, the code can be compiled and the
implementations of this class are used. Otherwise the compiler tries
to patch the missing implementation(s) with interface's default
implementation. And if there are multiple default implementations of a
method, then the diamond problem occurs and the compiler rejects the
compilation. Also if the class implements an interface's default
method, the implementation of the class will be used instead of
interfaces's default implementation.

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

The difference between abstract classes and interfaces in C# 8 release?

C# 8.0 introduces a new feature called Default implementations in Interfaces and this changes many things.

Interfaces can now have the default implementation of methods.
Interfaces can now have Private members.
Interfaces can now have static members, this is used for parameterization of the default implementation.
Interfaces can now have protected members which are not accessible by the derived class but can be accessible with a derived interface.
If a class wants to implement the protected member, it has to be done by implementing the interface explicitly.
Interfaces can also have virtual members, but the class can’t override the method but an interface can.

We can think that Interfaces and abstract are somewhat same now, But an interface cannot have Instance state, instance fields, instance auto-properties, cannot define class level fields or variables whereas an abstract class can have state.

There are some reasons stated for this change: Extending APIs, Interoperability with Android, iOS and supporting the traits language feature.



Related Topics



Leave a reply



Submit