猿问

当默认方法被子类的静态方法覆盖时,为什么 Java 8 编译失败?

在 model.addRow(row) 之后有一个 break 语句:


                // add row to the model


                    model.addRow(row);


                break; // breaks out of the while() { } loop.

Break 将退出当前代码块(如果嵌套在多个 fors/whiles/dos 中则更多)。这意味着它在执行一次后完全停止并跳出 while 循环。删除中断;行并让它运行不止一次


慕工程0101907
浏览 174回答 3
3回答

繁星coding

Father这里不是问题,因为来自接口的静态方法不是继承的(例如List.of(..)不能通过调用ArrayList.of(..))所以没有覆盖/隐藏,这也意味着没有冲突。因此我们可以安全地写interface Father {    static void method() { } }interface Child extends Father {    static void method() { } }问题是继承default void method() { }自接口的方法,这意味着之后MotherChildinterface 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被实例化的类继承),重点是首先要防止此类问题。这就是为什么我们被要求不能在一个地方(定义或继承)具有相同签名(名称+参数类型)的静态和非静态方法。

慕少森

这是一个有趣的情况。我认为简单的答案是静态方法从未被允许隐藏(它们不能覆盖)基类中的非静态方法。如果您static从 中删除修饰符Father,那也会导致 Child 无法编译。这可能是为了避免混淆。所以默认方法只是遵循现有规则。“但是等一下”,您可能会想,“添加默认方法的目的是明确允许库开发人员在不破坏现有代码的情况下将新功能引入旧接口。如果任何现有代码具有名称冲突的静态方法 - 不会它坏了?”其实我觉得不一定。IIRC,这是一个有意允许二进制兼容性和源兼容性不同的地方。我想你会发现如果:interface Child(和使用它的东西)已经被编译,而默认方法不存在于interface Mother, 和您稍后将默认方法添加到该源文件并仅interface Mother编译该源文件。然后我认为你最终会得到工作正常的代码(在字节码/JVM 级别)。但是,它会在您尝试针对 interface Child更新的interface Mother.

回首忆惘然

我还找到了解释更多案例的Oracle 教程。基本上在这里你可以找到一个摘要(从教程中提取):
随时随地看视频慕课网APP

相关分类

Java
我要回答