As a concrete example
sealed interface A permits B {
default void a() {
this.b();
}
}
non-sealed interface B extends A {
void b();
}
I know that this does not compile, but from a language perspective i don't understand what reason the compiler/compiler implementors would have to disallow it.
As @sepp2k commented, there is an obvious answer:
b()is not a member ofA.You are appealing to an intuition that says "sum types are sort of like union types" and "since
b()is in the intersection of all known types in the union 'A=B or nothing else', then we should be able to treatb()as being a member ofA". Besides "this just isn't how it works", consider how fragile such "duck typing" would be to changes in B, changes in the permits list of A, etc. And for what good reason?If
Awants to express a constraint that all its subclasses have a methodb(), there is a long-standing way to do that: thenAcan declare an abstractb(). Introducing this sort of complexity in the language for the corner case of "sealed class with only one subclass" would be pretty silly, when there is a trivially easy and safer way to do it already. "But I would have to type one more line of code in A" is not a good reason to wish for this sort of magic.