设有以下类型:
public interface Base {
default void sayHi(){
System.out.println("hi from base");
}
}
public interface Foo extends Base {
@Override
default void sayHi(){
System.out.println("hi from foo");
}
}
public interface Bar extends Base {
}
public class MyClass implements Foo, Bar {
public static void main(String[] args) {
MyClass c = new MyClass();
c.sayHi();
}
}
在这种情况下,如果main
执行,则打印“hi from foo”。为什么Foo
执行优先?不Bar
继承sayHi()
从Base
,因为如果MyClass
是仅实现Bar
,则Base
执行将被称为?因此,代码仍然无法编译是有意义的。另外,既然Bar
应该Base
执行sayHi()
,为什么我不能MyClass
像下面那样覆盖它:
@Override
public void sayHi() {
Bar.super.sayHi();
}
尝试这样做时会发生以下错误:
错误类型限定符Bar默认超级调用方法,sayHi()在Foo中被覆盖
发布于 2018-10-26 09:29:21
在JLS 9.4.1中几乎使用您的确切示例来指定此行为,只是更改了一些名称:
interface Top {
default String name() { return "unnamed"; }
}
interface Left extends Top {
default String name() { return getClass().getName(); }
}
interface Right extends Top {}
interface Bottom extends Left, Right {}
Right从Top继承name(),但Bottom从Left继承name(),而不是Right。这是因为Left中的name()会覆盖Top中name()的声明。
JLS似乎没有给出我能看到的任何特别具体的理由; 这就是Java设计者决定继承的方式。
发布于 2018-10-26 10:51:23
如果表单是TypeName。超级 [TypeArguments]标识符,然后:
在超级接口覆盖祖父表格接口中声明的方法的情况下,此规则通过简单地将祖父表添加到其直接超接口列表中来防止子接口“跳过”覆盖。访问祖父母的功能的适当方式是通过直接超级接口,并且仅当该接口选择暴露期望的行为时。(或者,开发人员可以自由定义他自己的附加超接口,通过超级方法调用公开所需的行为。)
https://stackoverflow.com/questions/-100005102
复制相似问题