Reputation: 5256
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
?
Upvotes: 16
Views: 4050
Reputation: 41
Final and non-sealed classes have some differences.
final class: you can't inherit this class, it's impossible to extend this class to other class on the other hand.
non-sealed class: it's possible to inherit this class from others.
For example:
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.
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";
}
}
So if you can try to inherit the Cat class, you can't, got compilation error because Cat class is final. On another hand, the Duck class is extendable because it's non-sealed class Like,
//Got Error
public class MyCat extends Cat {
.......
}
//Error not show.Duck class is extendable
public class MyDuck extends Duck {
.....
}
Upvotes: 4
Reputation: 704
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.
Upvotes: 0
Reputation: 4723
Cat
as final
, no other class can extend Cat
.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
.
Upvotes: 20