在 Java 16+ 中,密封到单个子类的类是否有任何理由无法访问该子类的方法?

问题描述

举个具体的例子

sealed interface A permits B {
    default void a() {
        this.b();
    }
}
    
non-sealed interface B extends A {
    void b();
}

我知道这不能编译,但从语言的角度来看,我不明白编译器/编译器实现者必须禁止它的原因。

解决方法

正如@sepp2k 所评论的,有一个明显的答案:b() 不是 A 的成员。

您正在诉诸一种直觉,即“和类型有点像联合类型”和“因为 b() 是联合中所有已知类型的交集'A=B or nothing else',那么我们应该能够将 b() 视为 A 的成员”。除了“这不是它的工作原理”之外,请考虑这种“鸭子输入”对于 B 中的更改、A 的许可列表中的更改等的脆弱性。还有什么充分的理由?

如果 A 想要表达一个约束,即它的所有子类都有一个方法 b(),有一个长期存在的方法来做到这一点:那么 A 可以声明一个抽象的 {{ 1}}。在语言中为“只有一个子类的密封类”的极端情况引入这种复杂性将是非常愚蠢的,因为已经有一种非常简单和安全的方法来做到这一点。 “但我必须在 A 中再输入一行代码”并不是希望这种魔法的好理由。