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