语言设计人员已经考虑过了,所以这些东西是由编译器强制执行的。因此,如果您定义:
interface First {
default void go() {
}
}
interface Second {
default void go() {
}
}
并且您为这两个接口实现了一个类:
static class Impl implements First, Second {
}
您将收到编译错误;并且您需要覆盖以免围绕它产生歧义。go
但是你可能会想,你可以在这里欺骗编译器,通过做:
interface First {
public default void go() {
}
}
static abstract class Second {
abstract void go();
}
static class Impl extends Second implements First {
}
你可能会认为它已经提供了一个实现,它应该没问题。这太照顾了,因此这也不会编译。First::go
Second::go
JLS 9.4.1.3 :类似地,当抽象和具有匹配签名的默认方法被继承时,我们会产生错误。在这种情况下,可以优先考虑其中一个 - 也许我们会假设默认方法也为抽象方法提供了合理的实现。但这是有风险的,因为除了巧合的名称和签名之外,我们没有理由相信默认方法的行为与抽象方法的契约一致 - 默认方法在最初开发子接口时甚至可能不存在。在这种情况下,更安全的做法是要求用户主动断言默认实现是合适的(通过重写声明)。
我要引入的最后一点,以巩固即使Java中添加了新内容也不允许多重继承,即来自接口的静态方法不会被继承。默认情况下,静态方法被继承:
static class Bug {
static void printIt() {
System.out.println("Bug...");
}
}
static class Spectre extends Bug {
static void test() {
printIt(); // this will work just fine
}
}
但是,如果我们为一个接口改变这一点(并且您可以实现多个接口,这与类不同):
interface Bug {
static void printIt() {
System.out.println("Bug...");
}
}
static class Spectre implements Bug {
static void test() {
printIt(); // this will not compile
}
}
现在,编译器禁止这样做,并且也是如此:JLS
JLS 8.4.8 : 一个类不会从它的超接口继承静态方法。