Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Interface with default methods vs abstract class, and what's the motivation?

Tags:

java

c#

Context

I've recently came across this C# proposal default interface methods I've read both the specification and more importantly the motivation. Possibly I missed something, but the motivation is a bit stinks me.

The only practical difference between interface and a fully abstract class was that a future class can implement (so be [IS A]) multiple interfaces, but can inherit (so be [IS A]) from only one abstract class, (and all the consequences)

What is not clear for me what is the exact difference between abstract classes and interfaces with default methods now, except that we can bring multiple (implementation) inheritance into the picture with default methods, which is not possible with abstract classes. (I do not want open the question/discussion is it good or bad, this is not the topic here)

However the motivation talks about completely different, three points:

  • "...API author to add methods to an interface in future versions without breaking source...". Well an "API" author can add methods to an abstract class also in a future version if he implements them without breaking anything.
  • "...enables C# to interoperate with APIs targeting Android (Java) and iOS (Swift),...". I think a language design decision, especially about abstractions and OOP patterns like multiple inheritance is a bit higher level than interoperate with Swift. I also think, this is only the 0.0x percent of interoperation issues, and also can be solved with other ways.
  • "...As it turns out, adding default interface implementations provides the elements of the "traits" language feature...". This is a very shallow statement, especially it refers to wikipedia "traits". By definition, traits allow adding methods without multiple inheritance (having [IS A] relationship with a super). However interfaces definitely are about [IS A]... Not talking about the fact, that traits are at least arguable good practice

Question

My question is what is the real difference (or motivation), or what am I missing?

like image 491
g.pickardou Avatar asked Oct 03 '17 07:10

g.pickardou


People also ask

Which is better to use interface or abstract class?

The short answer: An abstract class allows you to create functionality that subclasses can implement or override. An interface only allows you to define functionality, not implement it. And whereas a class can extend only one abstract class, it can take advantage of multiple interfaces.

Why interface methods are public and abstract by default?

Because by default all methods are abstract inside the interface. So this example states that we can not have final methods inside the interfaces. Hence, this example also shows that we can have abstract methods only inside the interface.

What are the advantages of interface over abstract classes?

The main advantages of interface over abstract class is to overcome the occurrence of diamond problem and achieve multiple inheritance. In java there is no solution provided for diamond problem using classes. For this reason multiple inheritance is block using classes in java.

Why we use interface instead of abstract?

Abstract classes should be used primarily for objects that are closely related, whereas interfaces are best suited for providing a common functionality to unrelated classes. Interfaces are a good choice when we think that the API will not change for a while.


1 Answers

They add this feature in Java 8. So you can add the Java tag and ask to Java developers what they can do with it. It also exists on Haskell and Scala apparently.

Multi-Inheritance

What come to my mind first is Multi-Inheritance. As a class can implement multiple interfaces, you can for example to solve the diamond problem.

In Java this is how they do:

public interface InterfaceA {
    public default void foo() {
        System.out.println("A -> foo()");
    }
}

public interface InterfaceB {
    public default void foo() {
        System.out.println("B -> foo()");
    }
}

private class Test implements InterfaceA, InterfaceB {
    // Compilation error : "class Test inherits unrelated defaults for foo() from types InterfaceA and InterfaceB"
}

So you have to either implement the methods (which override the default implementations) or call one of the super:

public class Test implements InterfaceA, InterfaceB {
     public void foo() {
        InterfaceB.super.foo();
    }
}
like image 168
fharreau Avatar answered Oct 05 '22 23:10

fharreau