Can abstract classes be in an allow only list in EK9?
← Sealed Types and Traits · Ref: Q300
No, abstract classes cannot appear in a trait's 'allow only' list. The list defines the exhaustive set of concrete runtime types that may implement the trait. Since abstract classes cannot be instantiated, listing them is meaningless.
ABSTRACT CLASSES ARE EXEMPT
Abstract classes can still implement sealed traits freely. They are exempt from the 'allow only' enforcement check because they cannot create runtime instances:
AbstractHelper with trait of SealedTrait as abstract override doWork() content <- "Abstract" require content?
BUT NOT IN THE LIST
The 'allow only' list may contain only concrete classes, so naming an abstract one is rejected with E05250:
defines module demo.sealed defines trait SealedTrait allow only AbstractBase, ConcreteA //ERROR E05250 doWork() as abstract defines class AbstractBase with trait of SealedTrait as abstract override doWork() content <- "Abstract" require content? ConcreteA with trait of SealedTrait override doWork() content <- "A" require content?
The corrected list names only the concrete class: 'SealedTrait allow only ConcreteA'.
TRANSITIVE CHECKING
Concrete subclasses of an abstract helper class that implements a sealed trait will be checked transitively. They must be in the 'allow only' list or get E05240.
See Q298 for 'allow only' basics. See Q299 for dispatcher exhaustiveness. See Q607 for why sealed classes must be open.
Example
defines module qa.sealedtraits.abstract.list defines trait Workable allow only ConcreteAlpha, ConcreteBeta doWork() as abstract defines class //AbstractHelper implements the sealed trait - allowed (abstract exempt) AbstractHelper with trait of Workable as abstract override doWork() content <- "Abstract" require content? //ConcreteAlpha is in the allow only list - allowed ConcreteAlpha with trait of Workable override doWork() content <- "Alpha" require content? //ConcreteBeta is in the allow only list - allowed ConcreteBeta is AbstractHelper override doWork() content <- "Beta" require content? defines function testAbstractExemption() alpha <- ConcreteAlpha() beta <- ConcreteBeta() require alpha? require beta?
Common mistakes
E05120 — Implementing an abstract method from a trait requires 'override'. Without it the compiler reports E05120 because the method signature is inherited. See ek9 -h E05120 for details.
Incorrect:
ConcreteAlpha with trait of Workable doWork()
Correct:
ConcreteAlpha with trait of Workable override doWork()
E05240 — A concrete class extending AbstractHelper inherits the sealed trait Workable, so sealing is checked transitively. UnlistedClass is not in the 'allow only' list, so the compiler reports E05240. See ek9 -h E05240 for details.
Incorrect:
ConcreteBeta is AbstractHelper override doWork() content <- "Beta" require content? UnlistedClass is AbstractHelper override doWork() content <- "Unlisted" require content?
Correct:
ConcreteBeta is AbstractHelper override doWork() content <- "Beta" require content?
E05240 — ConcreteAlpha is no longer in the 'allow only' list for the sealed trait Workable, yet it is still declared with 'with trait of Workable'. Only ConcreteBeta is permitted to implement it, so the unlisted concrete class triggers E05240. See ek9 -h E05240 for details.
Incorrect:
Workable allow only ConcreteBeta
Correct:
Workable allow only ConcreteAlpha, ConcreteBeta
Other ways to ask this
- Why can't abstract classes be in allow only?
- What happens if I put an abstract class in allow only?
- Does allow only work with abstract classes?
Coming from another language?
Java: sealed interfaces allow abstract classes in permits clause (different design choice). Kotlin: sealed hierarchy allows abstract intermediaries. Rust: no sealed traits, enums are always concrete. EK9: 'allow only' list is strictly for concrete types, abstract classes can implement freely but cannot be listed.
Keywords: runtime, abstract, only, allow, sealed, exhaustive, trait, permit, concrete, exempt, instantiate, allow-only, closed, list, class