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 //OK
BUT NOT IN THE LIST
The 'allow only' list should contain only concrete classes:
SealedTrait allow only ConcreteA, ConcreteB //CORRECT SealedTrait allow only AbstractBase, ConcreteA //ERROR: E05250
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()
E50010 — A concrete class extending AbstractHelper inherits the sealed trait Workable. If that concrete class is not in the 'allow only' list, the compiler rejects it because the sealed trait restricts which concrete types may implement it. See ek9 -h E50010 for details.
Incorrect:
UnlistedClass is AbstractHelper
Correct:
ConcreteBeta is AbstractHelper
E05240 — ConcreteGamma is not in the 'allow only' list for the sealed trait Workable. Only ConcreteAlpha and ConcreteBeta are permitted to implement it. Adding an unlisted concrete class triggers E02030. See ek9 -h E02030 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: exempt, concrete, permit, trait, exhaustive, sealed, allow, only, abstract, runtime, class, list, closed, allow-only, instantiate