I have 4 Classes that look like this:
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
}
Why can't I access the default implementation coming from extending Bar?
BarImplcan not invokeFoo’sdefaultmethod explicitly, asBarImplis not directly implementingFoo. It’s extendingBarwhich directly implementsFoo, hence, it’sBar’s decision to overrideFoo’sdefaultmethod or not.BarImplcan only invokeBar’sisEmpty()method viasuper.isEmpty(), which may end up atFoo’sdefaultmethod ifBardecides not to override it or at a concrete method ofBarif it does override it.Note that
T.super.method()can only be used if either,Tis a directly implemented super interface (i.e. not already implemented by a super class or another super interface) or ifTis an enclosing type of an inner class. The second use case is the reason for the “No enclosing instance of … is accessible in scope” error message.