Reputation: 9
In the following example why do I explicitly need to specify a class Square as non-sealed?
Isn't public class Square extends Shape {...}
more intuitive?
package com.example.geometry;
public abstract sealed class Shape permits Circle, Rectangle, Square {...}
public final class Circle extends Shape {...}
public sealed class Rectangle extends Shape permits TransparentRectangle, FilledRectangle {...} public final class TransparentRectangle extends Rectangle {...} public final class FilledRectangle extends Rectangle {...}
public non-sealed class Square extends Shape {...}
I could not see any explanation at JEP 360
Upvotes: 0
Views: 152
Reputation: 298153
You said you “could not see any explanation at JEP 360” but the linked document says explicitly:
A sealed class imposes three constraints on its permitted subclasses (the classes specified by its
permits
clause):
The sealed class and its permitted subclasses must belong to the same module, and, if declared in an unnamed module, the same package.
Every permitted subclass must directly extend the sealed class.
Every permitted subclass must choose a modifier to describe how it continues the sealing initiated by its superclass:
…
The last point indicates the intended mindset: a sealing is initiated by a class declared sealed
but is not just about the direct subclasses but the entire type hierarchy. Therefore, the permitted subclasses must declare, how to continue the sealing, either by being final
or sealed
or by explicitly declaring a re-opened branch of the class tree.
Opening (resp. accidentally breaking) a sealing by just not declaring an appropriate modifier, which could be an oversight, is not an option.
The available options are also listed directly under the cited part:
- A permitted subclass may be declared
final
to prevent its part of the class hierarchy from being extended further.- A permitted subclass may be declared
sealed
to allow its part of the hierarchy to be extended further than envisaged by its sealed superclass, but in a restricted fashion.- A permitted subclass may be declared
non-sealed
so that its part of the hierarchy reverts to being open for extension by unknown subclasses. (A sealed class cannot prevent its permitted subclasses from doing this.)
The JEP doesn’t mention it but the specification allows implicit declarations, so you don’t need to specify sealed
or final
for enum
or record
types implementing a sealed interface.
Upvotes: 5