7

Now, we know that Java 8 has introduced default and static methods in interfaces.
Interfaces were originally introduced in Java to avoid the diamond problem that occurred in C++, in multiple inheritance.

But along with the introduction of default methods in interfaces in Java 8, now, Java has also introduced the diamond problem, which it avoided in previous versions.

Default methods are not compulsorily needed to be overridden.
But when a diamond problemoccurs using interfaces, the class implementing those interfaces must override the default methods.

So now, I have three questions in my mind:

  1. Why is the need to have default methods?
  2. Couldn't we have multiple inheritance through classes itself, in place of having default methods in interfaces?
  3. And what was the need to avoid diamond problem in the previous versions, if they had to introduce it in Java 8 anyway?

Any good explanation or any link for explanation?

PS I did not find any link on the internet containing any good article on this.
All they said is that an abstract class gives you more concreteness.
As in, abstract classes can have constructors but interfaces cannot.

So again, I want to know, If abstract classes are more concrete, and can have constructors,
and anyways Java has introduced the diamond problem, why should we have interfaces now? Wouldn't abstract classes be good enough as a stand alone for multiple inheritance?

Aditya Singh
  • 2,343
  • 1
  • 23
  • 42
  • possible duplicate of [What are the differences between abstract classes and interfaces in Java 8?](http://stackoverflow.com/questions/22591499/what-are-the-differences-between-abstract-classes-and-interfaces-in-java-8) – assylias Jun 23 '14 at 12:26
  • This duplicate doesn't answer my question. So I won't consider it as a duplicate. Have a look at JB Nizet's answer's third comment for further clearance about what my question is. – Aditya Singh Jun 23 '14 at 12:35

3 Answers3

16

No, it didn't reintroduce the diamond problem, because interfaces still can't have any state, and default methods may not be final.

So, when you choose to implement two interfaces, you still have all the freedom you want to implement the default methods, either by choosing one of the provided default implementations, or by providing your own implementation. But you'll never have a problem of inheriting conflicting state from both interfaces, or inheriting two different final methods and not being able to resolve the conflict.

So, here are the answers to your questions:

  1. To be able to introduce new methods in existing interfaces without breaking backward compatibility: existing implementations will automatically implement these methods since their implementation is in the base interface.
  2. No, because that would introduce a diamond problem.
  3. Irrelevant
JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thanks, But do we really have the option to choose any one of the provided implementations? For example, if `interface A` and `interface B` both have a `public default void hello()` method, and `class Inheritance implements A, B`, then does `class Inheritance` have an option to choose `public default void hello()` from `interface A` and ignore it from `interface B` without overriding it? – Aditya Singh Jun 23 '14 at 12:08
  • 1
    Yes, it has. `public void hello() { A.super.hello(); }` – JB Nizet Jun 23 '14 at 12:10
  • And the same thing could also be achieved with classes. Had `A` and `B` been classes in place of interfaces, the same thing could be achieved with them too. So still my question stands, why do we need interfaces, if the same thing could be achieved with the help of classes? In place of `A.super.hello()` we could have something like `A.superClass.hello()` if `A` and `B` were classes and `Inheritance` extended them(Multiple inheritance with classes). `superClass` is no keyword. I am saying it just for the sake of explaining my point. – Aditya Singh Jun 23 '14 at 12:19
  • 2
    But doing it with classes would reintroduce the diamond problem, because suddenly you would inherit conflicting state from two classes, and one, or both of the methods could be final (and thus impossible to override). And anyway, it's irrelevant since the whole point of default methods was to be able to add new methods to existing **interfaces**. We want to be able to call list.sort() and list.forEach(). – JB Nizet Jun 23 '14 at 13:01
  • We make methods `final` if we don't want it to be overridden ever in life. So with multiple inheritance in mind, practically, we would never make those methods `final` which will be used for overriding purpose. So, I don't think that is an issue. Is it? – Aditya Singh Jun 23 '14 at 13:08
  • 1
    It is an issue because the language would be *forced to allow* this. Defender methods prevent the issue at the specification level. – Marko Topolnik Jun 24 '14 at 10:58
2

Regarding Point 1:

In order to support lambda expression for all collection classes, like forEach method, it was necessary to add something which will have backward compatibility.

see this video for detail Lambda Peak Under the hood

Vinit Prajapati
  • 1,593
  • 1
  • 17
  • 29
0
  1. Default methods make it possible to enhance an existing interface while providing binary compatibility with former versions of the interface to existing users.

See more here https://docs.oracle.com/javase/tutorial/java/IandI/nogrow.html

kiriloff
  • 25,609
  • 37
  • 148
  • 229