Java 8 - 两个接口包含具有相同方法签名但返回类型不同的默认方法,如何覆盖?

Ram*_*rma 5 java overriding interface java-8 default-method

我理解如果一个类实现包含同名默认方法的多个接口,那么我们需要在子类中重写该方法,以便明确定义我的方法将执行的操作.
问题是,见下面的代码:

interface A {
    default void print() {
        System.out.println(" In interface A ");
    }
}

interface B {
    default String print() {
        return "In interface B";
    }
}

public class C implements A, B {

    @Override
    public String print() {
        return "In class C";
    }

    public static void main(String arg[]) {
        // Other funny things
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,接口A和B都有一个名为'print'的默认方法,但我想覆盖接口B的print方法 - 返回字符串并按原样保留A的打印方式.但是这段代码不能编译给出:

Overrides A.print
The return type is incompatible with A.print()
Run Code Online (Sandbox Code Playgroud)

很明显,编译器试图覆盖A的打印方法,我不明白为什么!

Rad*_*def 3

这不可能。

8.4.8.3

如果具有返回类型的方法声明覆盖或隐藏了具有返回类型的另一个方法的声明,则返回类型必须可替换,否则会发生编译时错误。d1R1d2R2d1d2

8.4.5

具有返回类型的方法声明可以用返回类型替换另一个具有返回类型的方法,前提是满足以下任一条件:d1R1d2R2

  • 如果是那么就是。R1voidR2void

  • 如果是原始类型,则与 相同。R1R2R1

  • 如果是引用类型,则以下条件之一为真:R1

    • R1,适应于 的类型参数,是 的子类型。d2R2

    • R1可以通过未经检查的转换转换为 的子类型。R2

    • d1与、 和没有相同的签名。d2R1 = |R2|

换句话说,void原始方法和引用返回方法只能覆盖相同类别的方法以及被相同类别的方法覆盖。一个void方法只能重写另一个void方法,一个返回引用的方法只能重写另一个返回引用的方法,等等。

解决您遇到的问题的一种可能的解决方案是使用组合而不是继承:

class C {
    private A a = ...;
    private B b = ...;
    public A getA() { return a; }
    public B getB() { return b; }
}
Run Code Online (Sandbox Code Playgroud)

  • @Radiodef:在类文件格式中*是*可能的。所以是的,没有技术原因。 (2认同)