在Java 15的封闭类特性中,final类和非封闭类有什么区别?

huangapple go评论82阅读模式
英文:

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

问题

我有以下的密封接口(Java 15):

public sealed interface Animal permits Cat, Duck {

    String makeSound();
}

这个接口被两个类实现:

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-sealedDuck 有什么行为应用?

英文:

I have the following sealed interface (Java 15):

public sealed interface Animal permits Cat, Duck {

    String makeSound();
}

This interface is implemented by 2 classes:

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";
    }
}

Can someone tell me the difference between final and non-sealed? final stops me from creating other sub-classes but what behavior does non-sealed apply to Duck?

答案1

得分: 18

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

当将一个类标记为sealed时,所有直接扩展的类(位于permits子句之后的类)必须被标记为finalsealed或者non-sealed

  • 将一个扩展了sealed类的类标记为sealed,对它产生相同的影响:只有在permits子句之后指定的类才可以扩展它。

  • non-sealed只是“打破了封印”,因此不必将效果传递到层次结构下面。扩展的类对于未知子类再次开放,可以被其自身扩展。

  • final在效果上与在permits子句之后未指定任何类的sealed相同。请注意,不能在permits之后不指定任何内容,因此sealed无法取代final

英文:
  • As you've marked Cat as final, no other class can extend Cat.
  • As you've marked Duck as non-sealed, any class can extend Duck.

When marking a class as sealed, all directly extending classes (the ones after the permits clause) have to be marked either as final, sealed or non-sealed:

  • Marking a class that extends a sealed class as sealed, applies the same effect on it: Only classes specified after the permits clause are allowed to extend it.

  • non-sealed just "breaks the seal", so the effect doesn't have to be carried on down the hierarchy. The extending class is open (again) for being extended by unknown subclasses itself.

  • final is effectively the same as sealed without any class specified after the permits clause. Notice that specifying nothing after permits is not possible, so sealed cannot replace final.

答案2

得分: 2

final和non-sealed类有一些区别。

final类: 你不能继承这个类。我的意思是你不能将这个类扩展到其他类上。

non-sealed类: 你可以从其他类继承这个类。

例如:
这个封闭的接口,该接口只允许Cat和Duck类。请注意,Cat和Duck必须是final、non-sealed或sealed类。

public sealed interface Animal permits Cat, Duck {
    String makeSound();
}

现在,我正在创建Cat和Duck类。这里Cat是final类,另一个是non-sealed类。

public final class Cat implements Animal {

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

public class Duck implements Animal {

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

所以如果你尝试继承Cat类,你不能,会得到编译错误,因为Cat类是final类。另一方面,Duck类是可扩展的,因为它是non-sealed类。
例如,

// 得到错误
public class MyCat extends Cat {

    .......
}

// 错误不会显示。Duck类是可扩展的
public class MyDuck extends Duck {

    .......
}
英文:

Final and non-sealed class has some differences.

final class: you can't inherit this class. I mean that you can't extend this class to other class
on the other hand.

non-sealed class: you can inherit this class from others.

For example:<br>
This sealed interface which interface only permitted for Cat & Duck class.Note that Cat & Duck must be final , non-sealed or sealed class

public sealed interface Animal permits Cat, Duck {

    String makeSound();
}

Now, I am creating Cat & Duck class. Here Cat is the final class and another one is non-sealed class.

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-java -->

public final class Cat implements Animal {

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

public non-sealed class Duck implements Animal {

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

<!-- end snippet -->

So if you can try to inherit the Cat class, you can't, got compilation error because Cat class is final.On another hand Duck class is extendable because it's non-sealed class
Like,

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-java -->

//Got Error
public class MyCat extends Cat {

 .......
}

//Error not show.Duck class is extendable
public class MyDuck extends Duck {

    .....
}

<!-- end snippet -->

答案3

得分: 0

一种最终类别没有子类,意味着没有其他类可以扩展它。
任何类都可以扩展非密封类别。

当你将一个类标记为密封的时候,只有被许可的子类才能扩展它,并且只能具有这些修饰符 final、sealed 或 non-sealed:

public sealed class NumberSystem
    // 许可的子类条款已被省略
    // 因为所有的子类都存在于同一个文件中。
{ }
non-sealed class Decimal extends NumberSystem { .. }
final class NonRecurringDecimal extends Decimal {..}
final class RecurringDecimal extends Decimal {..}

尽管 NumberSystem 根层次的层次结构对于一组已知的类是封闭的,但你可以通过使用 non-sealed 关键字来允许子层次结构是开放的。

密封和非密封的组合允许你限制层次结构的某些部分,但不是全部。

在下面的图表中,我们将密封类别 NumberSystem 的根层次结构限制为一组已知的子类。然而,非密封类别 Decimal 允许任何未知的子类,比如 RecurringDecimal,来扩展它。

英文:

A final class has zero subclasses, meaning no other class can extend it.
Any class can extend the non-sealed class.

When you mark a class as sealed, only the permitted subclasses can extend it and can have only these modifiers final, sealed, or non-sealed:

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 {..}

Though, the NumberSystem root level hierarchy is closed to set of known classes, you can allow the sub hierarchies to be open by using the non-sealed keyword.

The sealed and non-sealed combination allows you to restrict parts of your hierarchy but not all.

In the below diagram, we restricted the root hierarchy of the sealed class NumberSystem to a known set of subclasses. However, the non-sealed Decimal class allows any unknown subclass such as RecurringDecimal to extend it.

huangapple
  • 本文由 发表于 2020年9月20日 02:34:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/63972130.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定