在 Java 8 中使用两个具有相同签名的默认方法实现两个接口
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22685930/
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
Implementing two interfaces with two default methods of the same signature in Java 8
提问by kavai77
Suppose I have two interfaces:
假设我有两个接口:
public interface I1
{
default String getGreeting() {
return "Good Morning!";
}
}
public interface I2
{
default String getGreeting() {
return "Good Afternoon!";
}
}
If I want to implement both of them, what implementation will be used?
如果我想同时实现它们,将使用什么实现?
public class C1 implements I1, I2
{
public static void main(String[] args)
{
System.out.println(new C1().getGreeting());
}
}
采纳答案by kavai77
This is a compile-time error. You cannot have two implementation from two interfaces.
这是一个编译时错误。你不能有来自两个接口的两个实现。
However, it is correct, if you implement the getGreeting
method in C1
:
但是,如果您在 中实现该getGreeting
方法,则它是正确的C1
:
public class C1 implements I1, I2 // this will compile, bacause we have overridden getGreeting()
{
public static void main(String[] args)
{
System.out.println(new C1().getGreeting());
}
@Override public String getGreeting()
{
return "Good Evening!";
}
}
I just want to add that even if the method in I1 is abstract, and default in I2, you cannot implement both of them. So this is also a compile-time error:
我只想补充一点,即使 I1 中的方法是抽象的,而 I2 中的默认方法,您也不能同时实现它们。所以这也是一个编译时错误:
public interface I1
{
String getGreeting();
}
public interface I2
{
default String getGreeting() {
return "Good afternoon!";
}
}
public class C1 implements I1, I2 // won't compile
{
public static void main(String[] args)
{
System.out.println(new C1().getGreeting());
}
}
回答by Keerthivasan
This is not specific to the question. But, I still think that it adds some value to the context. As an addition to @toni77's answer, I would like to add that the default method can be invoked from an implementing class as shown below. In the below code, the default method getGreeting()
from interface I1
is invoked from an overridden method:
这不是特定于问题的。但是,我仍然认为它为上下文增加了一些价值。作为@toni77 答案的补充,我想补充一点,可以从实现类调用默认方法,如下所示。在下面的代码中,默认方法getGreeting()
frominterface I1
是从重写的方法调用的:
public interface I1 {
default String getGreeting() {
return "Good Morning!";
}
}
public class C1 implements I1, I2 {
@override
public String getGreeting() {
return I1.super.getGreeting();
}
}
回答by Richard Tingle
If a class implements 2 interfaces both of which have a java-8 default method with the same signature (as in your example) the implementing class is obliged to override the method. The class can still access the default methodusing I1.super.getGreeting();
. It can access either, both or neither. So the following would be a valid implementation of C1
如果一个类实现了 2 个接口,这两个接口都有一个具有相同签名的 java-8 默认方法(如您的示例中所示),则实现类必须覆盖该方法。该类仍然可以使用访问默认方法I1.super.getGreeting();
。它可以访问其中一个,两者都可以访问,也可以都不访问。所以以下将是 C1 的有效实现
public class C1 implements I1, I2{
public static void main(String[] args)
{
System.out.println(new C1().getGreeting());
}
@Override //class is obliged to override this method
public String getGreeting() {
//can use both default methods
return I1.super.getGreeting()+I2.super.getGreeting();
}
public String useOne() {
//can use the default method within annother method
return "One "+I1.super.getGreeting();
}
public String useTheOther() {
//can use the default method within annother method
return "Two "+I2.super.getGreeting();
}
}
回答by TechTrip
There is a case where this actually works according to the resolution rules. If one of the interfaces extends one of the others.
有一种情况,根据解析规则,这实际上是有效的。如果接口之一扩展了其他接口之一。
Using the example from above:
使用上面的例子:
public interface I2 extends I1 {
default String getGreeting() {
return "Good Afternoon!";
}
}
The result would be:
结果将是:
Good Afternoon!
下午好!
However, I believe this is going to be a big problem. The whole reason for default interfaces is to allow library developers to evolve apis without breaking implementers.
但是,我相信这将是一个大问题。默认接口的全部原因是允许库开发人员在不破坏实现者的情况下发展 api。
Understandably they don't allow the methods to compile without the inheritance structure via extension because a library developer could potentially hiHyman behavior.
可以理解的是,它们不允许通过扩展在没有继承结构的情况下编译方法,因为库开发人员可能会劫持行为。
However, this has the potential to be self defeating. If a class implements two interfaces that are not related from a hierarchical view, but both define the same default method signature, then the class that extends both interfaces will not compile. (as demonstrated above)
然而,这有可能自我挫败。如果一个类实现了两个从层次结构视图中不相关的接口,但都定义了相同的默认方法签名,那么扩展这两个接口的类将不会编译。(如上所示)
It is conceivable that two different library developers could decide to add default methods at different times using common signatures; in fact it is probable that this will happen in libraries that implement similar concepts such as math libraries. If you happen to be the sorry soul implementing both interfaces in the same class you will be broken on update.
可以想象,两个不同的库开发人员可以决定在不同时间使用公共签名添加默认方法;事实上,这很可能会发生在实现类似概念的库中,例如数学库。如果您碰巧在同一个类中实现了两个接口,那么您将在更新时崩溃。
回答by Eddie B
I believe the rule is that the class implementing the duplicate default methods 'must' override the implementation.. The following compiles and runs fine...
我相信规则是实现重复默认方法的类“必须”覆盖实现..以下编译并运行良好......
public class DupeDefaultInterfaceMethods {
interface FirstAbility {
public default boolean doSomething() {
return true;
}
}
interface SecondAbility {
public default boolean doSomething() {
return true;
}
}
class Dupe implements FirstAbility, SecondAbility {
@Override
public boolean doSomething() {
return false;
}
}
public static void main(String[] args) {
DupeDefaultInterfaceMethods ddif = new DupeDefaultInterfaceMethods();
Dupe dupe = ddif.new Dupe();
System.out.println(dupe.doSomething());
}
}
> false