从间接继承的接口选择默认实现不起作用



我有四个类,看起来像这样:

public interface Foo<T> {
...
default boolean isEmpty() {
return false; //dummy value real implementation is not relevant for the problem
}
}
public interface CharSequence { //java.lang.CharSequence
...
default boolean isEmpty() {
return true; //dummy value real implementation is not relevant for the problem
}
public abstract class Bar<T> implements Foo<T> {
...
}
public final BarImpl extends Bar<Character> implements CharSequence { //typical diamond problem
...
@Override
public boolean isEmpty() { //needed to resolve diamond problem
return Foo.super.isEmpty() // Compile Error: No enclosing instance of the type Foo<T> is accessible in scope
return Bar.super.isEmpty() // Compile Error: No enclosing instance of the type Bar<T> is accessible in scope
return CharSequence.super.isEmpty() // compiles
}

为什么我不能访问来自扩展栏的默认实现?

BarImpl不能显式调用Foodefault方法,因为BarImpl没有直接实现Foo。它扩展了直接实现FooBar,因此,是否覆盖Foodefault方法由Bar决定。

BarImpl只能通过super.isEmpty()调用BarisEmpty()方法,如果Bar决定不重写Foodefault方法,则可能最终调用Bar的具体方法。

注意T.super.method()只能在T是直接实现的超接口(即没有被超类或其他超接口实现)或T是内部类的封闭类型时使用。第二个用例是">范围内没有…的封闭实例可访问"错误消息的原因。

import java.util.Objects;
class Test {
public static void main(String... arg) {
System.out.println(new BarImpl().isEmpty());
}
}
public interface Foo<T> {
default boolean isEmpty() {
System.out.println("  Foo's default method");
return false;
}
}
public abstract class Bar<T> implements Foo<T> {
}
public final class BarImpl extends Bar<Character> implements CharSequence {
@Override
public boolean isEmpty() {
System.out.println("calling (Bar) super.isEmpty();");
super.isEmpty();
System.out.println("calling CharSequence.super.isEmpty();");
return CharSequence.super.isEmpty();
}
public char charAt(int index) {
Objects.checkIndex(index, length());
return (char)('A' + index);
}
public int length() {
System.out.println("  length() [CharSequence's default method]");
return 26;
}
public CharSequence subSequence(int start, int end) {
Objects.checkFromToIndex(start, end, length());
return new StringBuilder(end - start).append(this, start, end);
}
public String toString() {
return new StringBuilder(length()).append(this, 0, length()).toString();
}
}
calling (Bar) super.isEmpty();
Foo's default method
calling CharSequence.super.isEmpty();
length() [CharSequence's default method]
false

相关内容

  • 没有找到相关文章