JDK 8 中的默认值是 Java 中多重继承的一种形式吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7857832/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 21:43:33  来源:igfitidea点击:

Are defaults in JDK 8 a form of multiple inheritance in Java?

javainterfaceclosuresmultiple-inheritancejava-8

提问by Pyrolistical

A new feature coming in JDK 8 allows you to add to an existing interface while preserving binary compatibility.

JDK 8 中的一项新功能允许您在保留二进制兼容性的同时添加到现有接口。

The syntax is like

语法就像

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

This way for all existing implementations of SomeInterfacewhen they upgrade to this new version they don't all suddenly have compiles errors around newInterface().

这样对于所有现有的实现,SomeInterface当他们升级到这个新版本时,他们不会突然在newInterface().

While this is neat, what happens when you are implementing two interfaces which both have added a new defaulted method which you did not implement? Let me explain with an example.

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

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();

Has this been defined as part of JDK 8 yet?

这是否已被定义为 JDK 8 的一部分?

I found the Java gods talking about something similar here http://cs.oswego.edu/pipermail/lambda-lib/2011-February/000068.html, but its part of private mailing list and I cannot ask them directly.

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

See this for more details on how defaults are going to be used in JDK 8 and extending the Collection interface to support lambdas: https://oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_Cho223662.pdf

有关如何在 JDK 8 中使用默认值以及扩展 Collection 接口以支持 lambdas 的更多详细信息,请参阅此内容:https: //oracleus.wingateweb.com/published/oracleus2011/sessions/25066/25066_Cho223662.pdf

回答by H-Man2

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.

我对你的问题的回答是:是的,它是多重继承的一种形式,因为你可以从不同的父母那里继承行为。缺少的是继承状态,即属性。

回答by Enkk

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.

? 类 TimeTravelingStudent 继承了 Present() 类型的不相关默认值,并且 Timeline 对 Present 的引用不明确,Timeline 中的方法 present() 和出勤匹配中的方法 present()。

回答by Andrejs

There are twoscenarios:

两种情况:

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

1)首先,提到了,那里没有最具体的界面

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:

2)其次,当有更具体的接口时:

   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
    }

回答by Eric Wang

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).

在 Java 8 中引入默认方法的主要目的是使接口可扩展,而不破坏现有的实现(有很多 3rd 方 Java 库)。

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

multiple inheritance像在C ++实际上是旨在避免的,这绝对不是在Java默认方法的目的。



How to override

如何覆盖

2 options:

2个选项:

  • 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>();
  • 用它自己的逻辑覆盖该方法。
  • 覆盖该方法,通过super, 格式调用接口的方法之一:<interface_name>.super.<method_name>();

Tips:

尖端:

  • method from interface is default to public, so don't forget to add publickeyword when override it.
  • 接口中的方法默认为public,所以public在覆盖它时不要忘记添加关键字。

回答by OlliP

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.

是的,但是您可以将 getter 和 setter 添加到实现类必须实现的接口中。然而,实现类不继承属性。所以,AFAICS,它更像是一个 trait 风格的解决方案,而不是一个多重继承风格的解决方案。

回答by mithil-studytrails

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 thistutorial for more details on how inheritance in default methods work.

如果有人仍在寻找答案,如果一个类使用相同的默认方法实现两个接口,则该类需要通过提供自己的实现来解决歧义。有关默认方法中的继承如何工作的更多详细信息,请查看教程。

回答by Mark Burleigh

"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

“我们如何区分方法”是Stackoverflow上的一个问题,在接口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 implementits own concrete methodof the interfaces A and B. Namely:

上面的类 C必须实现自己的接口 A 和 B的具体方法。 即:

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

To call a concrete implementationof a methodfrom a specific interface, you can instantiatethe interfaceand explicitly callthe concrete methodof that interface

要调用的具体实现一的方法,从一个特定的接口,你可以实例化接口显式调用具体方法是的接口

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

例如,以下代码从接口 A调用方法m()具体实现:

new A(){}.m();

The output of the above would be:

上面的输出将是:

Interface A: m()

接口A:m()

回答by Peter

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.

在我看来,它不是多重继承,因为它们是无状态的。所以虚拟扩展方法不支持完整的对象或类功能。