英文:
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";
}
}
有人可以告诉我 final
和 non-sealed
之间的区别吗? final
阻止我创建其他子类,但是 non-sealed
对 Duck
有什么行为应用?
英文:
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
子句之后的类)必须被标记为final
、sealed
或者non-sealed
:
-
将一个扩展了
sealed
类的类标记为sealed
,对它产生相同的影响:只有在permits
子句之后指定的类才可以扩展它。 -
non-sealed
只是“打破了封印”,因此不必将效果传递到层次结构下面。扩展的类对于未知子类再次开放,可以被其自身扩展。 -
final
在效果上与在permits
子句之后未指定任何类的sealed
相同。请注意,不能在permits
之后不指定任何内容,因此sealed
无法取代final
。
英文:
- As you've marked
Cat
asfinal
, no other class can extendCat
. - As you've marked
Duck
asnon-sealed
, any class can extendDuck
.
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 assealed
, applies the same effect on it: Only classes specified after thepermits
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 assealed
without any class specified after thepermits
clause. Notice that specifying nothing afterpermits
is not possible, sosealed
cannot replacefinal
.
答案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 "miau";
}
}
public non-sealed class Duck implements Animal {
@Override
public String makeSound() {
return "quack";
}
}
<!-- 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论