Why can't I extend a class in EK9?
← Classes and OOP · Ref: Q784
EK9 classes are CLOSED by default — they cannot be extended unless explicitly marked 'as open'. This is the opposite of Java (where classes are open by default) and the same as Kotlin.
WHY CLOSED BY DEFAULT
1. Extending a class creates tight coupling between parent and child
2. The parent must be designed for inheritance (fragile base class problem)
3. Composition is almost always better than inheritance
4. Built-in types (List, Dict, Optional) are deliberately closed
HOW TO MAKE EXTENSIBLE
MyClass as open // Now it can be extended MyClass as abstract // Abstract classes are implicitly open
COMPOSITION ALTERNATIVE
Instead of extending a closed class, wrap it as a field:
MyWrapper
items as List of String
add(item as String)
items += item
THIS EXAMPLE
The Shape class is marked 'as open' so Circle can extend it. The Config class is closed — the program uses it directly.
See Q83 for why closed by default. See Q84 for the open modifier. See Q85 for composition.
Example
defines module qa.classesandoop.closedbydefault defines class Shape as open name <- String() Shape() -> n as String name :=: n describe() <- rtn as String: name default operator ? Circle extends Shape radius <- Float() Circle() -> n as String r as Float super(n) radius :=: r override describe() <- rtn as String: `${super.describe()} r=${radius}` default operator ? ItemHolder items <- List() of String addItem() -> item as String items += item count() <- rtn as Integer: length items default operator ? defines program ShowShapes() stdout <- Stdout() circle <- Circle("circle", 5.0) if circle? stdout.println(circle.describe()) holder <- ItemHolder() holder.addItem("one") holder.addItem("two") stdout.println($holder.count())
Common mistakes
E05030 — Removing 'as open' makes Shape closed. Circle cannot extend a closed class. Either add 'as open' to Shape, or use composition instead of inheritance. See ek9 -h E05030 for details.
Incorrect:
Shape
name <- String()
Correct:
Shape as open name <- String()
E05030 — List is a built-in closed type — it cannot be extended. Use composition: hold a List as a field instead of inheriting from it. See ek9 -h E05030 for details.
Incorrect:
ItemList extends List of String addItem()
Correct:
items <- List() of String addItem()
Other ways to ask this
- What triggers E05030 not open to extension?
- Why are EK9 classes closed by default?
- How do I make a class extensible in EK9?
Coming from another language?
Java: classes open by default, use 'final' to close. Python: classes always open. Rust: no class inheritance. Kotlin: classes closed by default, use 'open' keyword (same as EK9). Go: no class inheritance, composition only. C#: classes open by default, use 'sealed' to close. EK9: closed by default like Kotlin, 'as open' to allow extension.
Keywords: final, sealed, extends, default, inheritance, open, composition, closed, E05030