假设有以下几种类型:
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是否继承了Base的sayHi(),因为如果MyClass只实现Bar,那么Base实现就会被调用?所以代码仍然没有编译是有意义的。此外,既然Bar应该有Base的< code >D11的实现,为什么我不能在MyClass中重写它,比如:
@Override
public void sayHi() {
Bar.super.sayHi();
}尝试这样做时会发生以下错误:
默认超级调用方法中的错误类型限定符栏,sayHi()在Foo中被重写
发布于 2016-05-12 21:21:37
此行为是使用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 {}右侧从Top继承name(),底部从左侧继承name(),而不是从右继承。这是因为左侧的name()覆盖了Top中的name()声明。
JLS似乎没有给出任何我能看到的特别具体的理由;这正是Java设计人员决定继承将如何工作的原因。
发布于 2016-05-12 21:23:03
这是故意的。来自JLS 15.12.3
如果表单是TypeName的话。超棒的。然后,TypeArguments标识符:
在超级接口覆盖在祖父母接口中声明的方法的情况下,该规则通过简单地将祖父母添加到其直接超级接口列表中,防止子接口“跳过”覆盖。访问祖父母的功能的适当方法是通过直接的超级接口,并且只有当该接口选择公开所需的行为时。(或者,开发人员可以自由地定义自己的附加超级接口,该超级接口通过超级方法调用公开所需的行为。)
发布于 2022-09-21 05:45:14
为什么Foo的实现优先?既然Bar应该有Base的sayHi()实现,为什么我不能重写呢?
已被其他候选项覆盖的方法将被忽略。当超级类型有一个共同的祖先时,就会出现这种情况。
https://stackoverflow.com/questions/37197301
复制相似问题