Can an abstract class appear in a trait's allow only list?

← Sealed Types and Traits · Ref: Q850

A trait's 'allow only' list must contain only concrete classes. Abstract classes cannot be instantiated, so listing them in 'allow only' is meaningless and raises E05250.

WHY ONLY CONCRETE CLASSES

The 'allow only' mechanism restricts which classes can implement a trait. Since abstract classes cannot be instantiated directly, allowing them would create a gap: any concrete subclass of that abstract class could implement the trait without being explicitly listed. This defeats the purpose of sealing.

CORRECT PATTERN

List only concrete, instantiable classes:

  Workable allow only FastWorker, SlowWorker
    execute() as abstract
      <- rtn as String?

INCORRECT PATTERN

  defines module demo.sealed
    defines trait
      Workable allow only AbstractHelper, ConcreteWorker  //ERROR E05250
        execute() as abstract
          <- rtn as String?
    defines class
      AbstractHelper with trait of Workable as abstract
        override execute()
          <- rtn as String: "abstract"
      ConcreteWorker with trait of Workable
        override execute()
          <- rtn as String: "work"

See Q298 for 'allow only' on traits. See Q300 for abstract classes and allow only. See Q608 for sealed classes versus sealed traits.

Example

defines module qa.sealed.allow.only.concrete

  defines class

    <?-
      Abstract helper class — cannot appear in allow only lists.
    -?>
    AbstractHelper as abstract
      execute() as abstract
        <- rtn as String?
      default operator ?

    <?-
      First concrete worker class.
      Can appear in allow only lists because it is concrete.
    -?>
    FastWorker
      execute()
        <- rtn as String: "fast"
      default operator ?

    <?-
      Second concrete worker class.
      Also eligible for allow only lists.
    -?>
    SlowWorker
      execute()
        <- rtn as String: "slow"
      default operator ?

  defines trait

    <?-
      Trait sealed to only FastWorker and SlowWorker.
      No other class can implement this trait.
    -?>
    Workable allow only FastWorker, SlowWorker
      execute() as abstract
        <- rtn as String?

  defines program

    AllowOnlyDemo()
      stdout <- Stdout()

      fast <- FastWorker()
      if fast?
        stdout.println(fast.execute())

Common mistakes

E05250 — Abstract classes cannot appear in allow only lists because they cannot be instantiated. Only list concrete classes that will implement the trait. See ek9 -h E05250 for details.

Incorrect:

    Workable allow only AbstractHelper, SlowWorker

Correct:

    Workable allow only FastWorker, SlowWorker
Other ways to ask this
  • What is E05250 in EK9?
  • Why must allow only list concrete classes?
  • What types can appear in allow only?
  • Can I seal a trait to abstract classes?

Coming from another language?

Java: sealed interfaces permit abstract classes (different design). Kotlin: sealed interfaces allow abstract implementations. Rust: no sealed traits (crate visibility instead). Scala: sealed traits allow abstract subtypes. EK9: E05250 requires all allow only entries to be concrete classes.

Keywords: only, implement, instantiate, restrict, abstract, E05250, allow, concrete, sealed, trait