JDK 8中的默认设置是 Java 中的一种多重继承吗?

JDK8中的一个新特性允许您在保持二进制兼容性的同时添加到现有接口。

语法就像

public interface SomeInterface() {
void existingInterface();
void newInterface() default SomeClass.defaultImplementation;
}

这样,当所有现有的 SomeInterface实现升级到这个新版本时,它们不会突然在 newInterface()附近出现编译错误。

虽然这是整洁的,但是当您实现两个接口时会发生什么,这两个接口都添加了一个新的默认方法,而您没有实现这个方法?让我用一个例子来解释。

public interface Attendance {
boolean present() default DefaultAttendance.present;
}


public interface Timeline {
boolean present() default DefaultTimeline.present;
}


public class TimeTravelingStudent implements Attendance, Timeline {


}


// which code gets called?
new TimeTravelingStudent().present();

这已经被定义为 JDK 8的一部分了吗?

我发现 Java 之神在这里谈论类似的东西 http://cs.oswego.edu/pipermail/lambda-lib/2011-February/000068.html,但它的私人邮件列表的一部分,我不能直接问他们。

有关如何在 JDK 8中使用默认值以及扩展 Collection 接口以支持 lambdas 的更多细节,请参见: Https://oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_cho223662.pdf

20717 次浏览

The answer to the duplicate operation is:

To solve multiple inheritance issue a class implementing two interfaces providing a default implementation for the same method name and signature must provide an implementation of the method. [Full Article]

My answer to your question is: Yes, it is a form of multiple inheritance, because you can inherit behavior from different parents. What's missing is to inherit states, i. e., attributes.

My answer to your question is: Yes, it is a form of multiple inheritance, because you can inherit behavior from different parents. What's missing is to inherit states, i. e., attributes.

Yes, but you can add getters and setters to your interface that the implementing classes then must implement. Nevertheless, the implementing classes don't inherit attributes. So, AFAICS, it's more like a trait-style solution rather than a multiple inheritance style solution.

I know this is a old post, but as i'm working with this stuff...

You will have an error from the compiler, telling you that:

 class TimeTravelingStudent inherits unrelated defaults for present() from types Attendance and Timeline reference to present is ambiguous, both method present() in Timeline and method present() in Attendance match.

As far as I see it, it is no multiple inheritance because they are stateless. So virtual extension methods don't support full object or class functionality.

If anyone's still looking for an answer, in case a class implements two interfaces with the same default method then the class needs to resolve the disambiguity by providing an implementation of its own. Look at this tutorial for more details on how inheritance in default methods work.

In short: it's a compile time error, must override the method by hand in the implementation.


Purpose of default method

The major purpose to introduce default method in Java 8, is to make interface extendable, without breaking existing implementations (there are so many 3rd party Java libraries).

And multiple inheritance like in C++ is actually intended to be avoided, that's definitely not the purpose of default method in Java.


How to override

2 options:

  • Override the method, with its own logic.
  • Override the method, call one of the interface's method via super, format: <interface_name>.super.<method_name>();

Tips:

  • method from interface is default to public, so don't forget to add public keyword when override it.

There are two scenarios:

1) First, that was mentioned, where there is no most specific interface

public interface A {
default void doStuff(){ /* implementation */ }
}


public interface B {
default void doStuff() { /* implementation */ }
}


public class C implements A, B {
// option 1: own implementation
// OR
// option 2: use new syntax to call specific interface or face compilation error
void doStuff(){
B.super.doStuff();
}
}

2) Second, when there IS a more specific interface:

   public interface A {
default void doStuff() { /* implementation */ }
}


public interface B extends A {
default void doStuff() { /* implementation */ }
}


public class C implements A, B {
// will use method from B, as it is "closer" to C
}

"How will we distinguish the methods" was a question that was put on Stackoverflow and referred to this question concrete methods in interfaces Java1.8

The following is an example that should answer that question:

interface A{
default public void m(){
System.out.println("Interface A: m()");
}
}


interface B{
default public void m(){
System.out.println("Interface B: m()");
}
}


class C implements A,B {


public void m(){
System.out.println("Concrete C: m()");
}


public static void main(String[] args) {
C aC = new C();
aC.m();
new A(){}.m();
new B(){}.m();
}
}

Class C above must implement its own concrete method of the interfaces A and B. Namely:

 public void m(){
System.out.println("Interface C: m()");
}

To call a concrete implementation of a method from a specific interface, you can instantiate the interface and explicitly call the concrete method of that interface

For example, the following code calls the concrete implementation of the method m() from interface A:

new A(){}.m();

The output of the above would be:

Interface A: m()