3 回答
TA贡献1797条经验 获得超4个赞
Father这里不是问题,因为来自接口的静态方法不是继承的(例如List.of(..)不能通过调用ArrayList.of(..))所以没有覆盖/隐藏,这也意味着没有冲突。
因此我们可以安全地写
interface Father {
static void method() { }
}
interface Child extends Father {
static void method() { }
}
问题是继承default void method() { }自接口的方法,这意味着之后MotherChild
interface Child extends Father, Mother {
static void method() { }
}
你最终会得到有两个method()版本的接口:静态和非静态(默认)
interface Child extends Father, Mother {
static void method() { }
default void method() { } //inherited from Mother
}
但为什么这是个问题?
假设您想向Child接口添加另一个方法,该方法将调用method()
interface Child extends Father, Mother {
static void method() { }
default void method() { } //inherited from Mother
default void demo(){
method(); //which code block should be executed?
}
}
它应该从静态方法() 还是从默认方法() 执行代码?编译器将无法决定。
虽然这种情况可以通过使用来解决
Child.method()对于静态方法,
this.method()对于默认方法(是的,它不会有歧义,因为静态方法不会this被实例化的类继承),
重点是首先要防止此类问题。这就是为什么我们被要求不能在一个地方(定义或继承)具有相同签名(名称+参数类型)的静态和非静态方法。
TA贡献2019条经验 获得超9个赞
这是一个有趣的情况。我认为简单的答案是静态方法从未被允许隐藏(它们不能覆盖)基类中的非静态方法。如果您static从 中删除修饰符Father,那也会导致 Child 无法编译。这可能是为了避免混淆。
所以默认方法只是遵循现有规则。
“但是等一下”,您可能会想,“添加默认方法的目的是明确允许库开发人员在不破坏现有代码的情况下将新功能引入旧接口。如果任何现有代码具有名称冲突的静态方法 - 不会它坏了?”
其实我觉得不一定。IIRC,这是一个有意允许二进制兼容性和源兼容性不同的地方。我想你会发现如果:
interface Child(和使用它的东西)已经被编译,而默认方法不存在于interface Mother, 和您稍后将默认方法添加到该源文件并仅
interface Mother编译该源文件。
然后我认为你最终会得到工作正常的代码(在字节码/JVM 级别)。但是,它会在您尝试针对 interface Child更新的interface Mother.
添加回答
举报

