Can a permitted subclass also be sealed in EK9?
← Sealed Types and Traits · Ref: Q303
Yes! A permitted subclass can itself be sealed, creating a chained hierarchy. Enforcement is transitive: all descendants must appear in every ancestor's allow only list.
CHAINED SEALING EXAMPLE
Vehicle allow only Car, Truck, Sedan, Hatchback as open Car extends Vehicle allow only Sedan, Hatchback as open Sedan extends Car Hatchback extends Car Truck extends Vehicle
TRANSITIVE ENFORCEMENT
Sedan and Hatchback extend Car, but Car extends Vehicle. Because Vehicle is sealed, Sedan and Hatchback must also appear in Vehicle's allow only list. This is transitive: every sealed ancestor must explicitly permit the descendant.
ENFORCEMENT AT EACH LEVEL
- Vehicle permits: Car, Truck, Sedan, Hatchback
- Car permits: Sedan, Hatchback only
- Truck has no allow only list of its own, but it is not 'as open' either, so nothing can extend it. If it were opened, any subclass would still have to be listed in Vehicle's allow only list (E05240)
This works with both classes and traits. Each sealed level provides its own exhaustive set.
See Q301 for sealed class basics, Q298 for sealed traits.
Example
defines module qa.sealedclasses.chained defines class Vehicle allow only Car, Truck, Sedan, Hatchback as open describe() <- rtn as String: "Vehicle" Car extends Vehicle allow only Sedan, Hatchback as open override describe() <- rtn as String: "Car" Sedan extends Car override describe() <- rtn as String: "Sedan" Hatchback extends Car override describe() <- rtn as String: "Hatchback" Truck extends Vehicle override describe() <- rtn as String: "Truck" defines function testChainedSealing() sedan <- Sedan() hatchback <- Hatchback() truck <- Truck() require sedan? require hatchback? require truck?
Common mistakes
E05270 — EK9 classes are closed by default, and a class with 'allow only' must be declared 'as open'. Without 'as open' the compiler reports E05270 on Vehicle (and each subclass is also rejected as the type is not open for extension). See ek9 -h E05270 for details.
Incorrect:
Vehicle allow only Car, Truck, Sedan, Hatchback
Correct:
Vehicle allow only Car, Truck, Sedan, Hatchback as open
E05240 — Sedan and Hatchback extend Car which extends Vehicle. Because Vehicle is sealed, all concrete descendants including Sedan and Hatchback must appear in Vehicle's 'allow only' list. Omitting them triggers E05240. See ek9 -h E05240 for details.
Incorrect:
Vehicle allow only Car, Truck as open
Correct:
Vehicle allow only Car, Truck, Sedan, Hatchback as open
E05120 — Overriding the describe() method inherited from Vehicle requires the 'override' keyword. Omitting it triggers E05120. See ek9 -h E05120 for details.
Incorrect:
Car extends Vehicle allow only Sedan, Hatchback as open describe() <- rtn as String: "Car"
Correct:
Car extends Vehicle allow only Sedan, Hatchback as open override describe() <- rtn as String: "Car"
E05240 — SUV extends Vehicle but is not in 'Vehicle allow only Car, Truck, Sedan, Hatchback'. A class must be listed in every sealed ancestor's 'allow only' list; adding SUV without updating Vehicle's list triggers E05240. See ek9 -h E05240 for details.
Incorrect:
Truck extends Vehicle override describe() <- rtn as String: "Truck" SUV extends Vehicle override describe() <- rtn as String: "SUV"
Correct:
Truck extends Vehicle override describe() <- rtn as String: "Truck"
Other ways to ask this
- How does chained sealing work in EK9?
- Can I have nested allow only in EK9?
- How do I create a multi-level sealed hierarchy?
Coming from another language?
Java: sealed class hierarchies with permits at each level (Java 17+). Kotlin: sealed classes in same file, nested sealed hierarchies supported. EK9: chained allow only provides the same hierarchical sealing.
Keywords: closed, class, chained, extend, permit, exhaustive, hierarchy, sealed, allow-only, allow, level, only, nested