在Java 8中使用两个具有相同签名的默认方法实现两个接口

kav*_*i77 44 java interface java-8

假设我有两个接口:

public interface I1
{
    default String getGreeting() {
        return "Good Morning!";
    }
}

public interface I2
{
    default String getGreeting() {
        return "Good Afternoon!";
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想实现它们,将使用什么实现?

public class C1 implements I1, I2
{
    public static void main(String[] args)
    {
        System.out.println(new C1().getGreeting());
    }
}
Run Code Online (Sandbox Code Playgroud)

kav*_*i77 59

这是编译时错误.您不能从两个接口实现两个实现.

但是,如果您在以下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!";
    }
}
Run Code Online (Sandbox Code Playgroud)

我只想补充一点,即使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());
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 请注意,如果 I2 没有带有重复签名的默认方法,这将编译并运行(当然)。如果随后将该默认方法添加到 I2,则在编译 I1 和 C1 之后,C1(之前运行良好)将引发运行时错误。这是对向现有接口添加默认方法是“安全”的想法的一个重要警告 - 在某些情况下这样做可能会破坏现有代码。如果您正在维护库,考虑这一点非常重要。 (2认同)

Kee*_*san 24

这不是特定的问题.但是,我仍然认为它为上下文增加了一些价值.作为@ toni77的答案的补充,我想补充一下,可以从实现类调用默认方法,如下所示.在下面的代码,默认方法getGreeting()interface I1选自重写的方法调用:

public interface I1 {
     default String getGreeting() {
        return "Good Morning!";
     }
}

public class C1 implements I1, I2 {       
    @override
    public String getGreeting() {
        return I1.super.getGreeting();
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你的I2接口是空的吗? (3认同)

Ric*_*gle 9

如果一个类实现了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();
    }


}
Run Code Online (Sandbox Code Playgroud)