How do I extend a base whose no-argument constructor is private (E07176 / E07177)?

← Constructor Delegation · Ref: Q1353

A base whose properties are uninitialised must make its no-arg default 'private' (E07175). That private default is NOT accessible to a sub-type, and EVERY constructor chains to a super constructor - explicitly (super(...) / this(...)) or via a hidden IMPLICIT super() to the super's no-arg. So a sub-type cannot reach the private base default.

WHAT HAPPENS

1. A sub-type that WRITES a no-arg default (or any constructor with no explicit super(...)) implicitly calls the private base default -> E07176.
2. A sub-type with NO constructor at all: EK9 would normally synthesise a public no-arg default, but its hidden super() cannot reach the private base default, so none is synthesised - the type is unconstructable -> E07177.

THE FIX: call an accessible initialising super(...)

  Shape as abstract
    name as String?
    default private Shape() as pure
    Shape() as pure
      -> n as String
      name :=? String(n)
  Circle is Shape
    Circle() as pure
      super("circle")          // reaches the accessible, initialising Shape(String)

EK9 does not mandate a no-argument constructor - the sub-type simply has none, and is constructed via the constructor that calls super(...).

See Q886 for E07175 (private default). See Q581 for super() delegation. See Q1346 for the 'T?' null-safety idiom.

Example

defines module qa.constructordelegation.privatesuperconstructor

  defines class

    Shape as abstract
      name as String?

      //Uninitialised property -> the no-arg default must be private (E07175). That private default is not
      //reachable by any sub-type, so sub-types must chain to the accessible initialising Shape(String).
      default private Shape() as pure

      Shape() as pure
        -> n as String
        name :=? String(n)

      name() as pure
        <- rtn as String: String(name)

      default operator ?

    //Correct: Circle calls an accessible, initialising super(...). It has no synthesised no-arg default
    //(EK9 does not mandate one) - it is constructed via this constructor.
    Circle is Shape
      Circle() as pure
        super("circle")

  defines program

    PrivateSuperDemo()
      stdout <- Stdout()

      c <- Circle()
      stdout.println(c.name())

Common mistakes

E07176 — A written 'default Circle()' (or any constructor without an explicit super(...)) implicitly calls the private Shape() - not accessible. Call an accessible initialising super(...) instead. See ek9 -h E07176.

Incorrect:

default Circle() as pure

Correct:

Circle() as pure
        super("circle")

E07177 — A sub-type with NO constructor cannot have a public default synthesised (its implicit super() could not reach the private Shape()). Define a constructor that calls an accessible super(...). See ek9 -h E07177.

Incorrect:

Circle is Shape

Correct:

Circle() as pure
        super("circle")
Other ways to ask this
  • Why does my sub-type get E07176 'constructor cannot call a private super constructor'?
  • E07177 the super type's no-argument constructor is private — what do I do?
  • My 'default Sub()' is rejected because the base has 'default private Base()'
  • A sub-class with no constructor won't compile when the super default is private

Coming from another language?

Java/Kotlin: a subclass constructor implicitly calls super() and fails to compile if the base no-arg constructor is inaccessible ('there is no default constructor available'). EK9 reports the same class of problem precisely: E07176 when a sub-type constructor chains (implicitly or explicitly) to a private super, and E07177 when no constructor exists at all and no default can be synthesised.

Keywords: E07177, super, constructor, CONSTRUCTOR_USES_PRIVATE_SUPER, E07176, default, delegation, uninitialised, sub-type, abstract, inheritance, private, CONSTRUCTOR_REQUIRED_FOR_PRIVATE_SUPER, implicit