Java 15 的 sealed-classes 特征中的最终和非密封 class 有什么区别?

What is the difference between a final and a non-sealed class in Java 15's sealed-classes feature?

我有如下密封接口(Java15):

public sealed interface Animal permits Cat, Duck {

    String makeSound();
}

该接口由2实现类:

public final class Cat implements Animal {

    @Override
    public String makeSound() {
        return "miau";
    }
}

public non-sealed class Duck implements Animal {

    @Override
    public String makeSound() {
        return "quack";
    }
}

谁能告诉我 finalnon-sealed 之间的区别? final 阻止我创建其他子 类 但是 non-sealed 有什么行为适用于 Duck

  • 由于您已将 Cat 标记为 final,其他 class 无法扩展 Cat
  • 由于您已将 Duck 标记为 non-sealed,任何 class 都可以扩展 Duck

当将 class 标记为 sealed 时,所有直接扩展 class 的元素(在 permits 子句之后的)都必须标记为 finalsealednon-sealed:

  • sealed class 扩展为 sealed 的 class 标记为 sealed,对其应用相同的效果:仅 class在 permits 子句之后指定的 es 允许扩展它。

  • non-sealed 只是“打破封印”,所以效果不必向下层级传递。扩展 class 已(再次)开放,供未知子classes 本身扩展。

  • final 实际上sealed 相同,但 permits 后没有指定任何 class条款。请注意,在 permits 之后不指定任何内容是不可能的,因此 sealed 无法替换 final.

最终的 class 有零个子 class,这意味着没有其他 class 可以扩展它。 任何 class 都可以扩展非密封 class.

当您将 class 标记为密封时,只有允许的子classes 可以扩展它并且只能具有这些修饰符最终的、密封的或非密封的:

public sealed class NumberSystem
    // The permits clause has been omitted
    // as all the subclasses exists in the same file.
{ }
non-sealed class Decimal extends NumberSystem { .. }
final class NonRecurringDecimal extends Decimal {..}
final class RecurringDecimal extends Decimal {..}

尽管 NumberSystem 根级层次结构对一组已知 classes 是封闭的,但您可以使用 non-sealed 关键字允许打开子层次结构。

密封和非密封组合允许您限制部分而不是全部层次结构。

在下图中,我们将密封的 class NumberSystem 的根层次结构限制为一组已知的子classes。然而,non-sealed Decimal class 允许任何未知的子 class 例如 RecurringDecimal 来扩展它。