E10030: use of a constructor directly on an abstract type is not permitted.
What went wrong
You're trying to create an instance of an ABSTRACT type directly. Abstract types cannot be instantiated - only concrete subtypes can.
IMPORTANT: Parameterizing an abstract generic type does NOT make it concrete.
- 'Iterator of String' is STILL abstract
- 'Consumer of String' is STILL abstract
THROUGH A GENERIC: every T() in a generic becomes a constructor call on the type that parameterises it. A generic whose no-arg constructor does 'item: T()', used with an abstract type ('Holder(square)' with 'square as Shape'), is this error - even when that constructor is private and never called.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 841 (Why can't I instantiate an abstract generic type like Ite...)
- ek9 -q 2020 (How do I write a generic type that can be parameterised w...)
Rationale
Abstract types define interfaces without full implementation. Parameterizing preserves abstract nature.
How to fix it
- Use a concrete subtype
- For function types, provide implementation body
- Get iterators from concrete collections
- When the abstract type reaches T() through a generic parameterisation, make that generic's no-arg constructor private and do not call T() in it - leave the T property unset and construct through the value constructor ('default private Holder()' plus 'Holder() -> initial as T'). Nothing can then observe the unset property: a construction call reaching the private no-arg is E08264.
Common causes
- Calling a constructor on an abstract GENERIC type ('Iterator() of String'); on a non-generic abstract class or trait the error is E50080
- Calling constructor on parameterized abstract generic
- Forgetting generic parameterization preserves abstractness
- A generic's T() (often 'item: T()' in its no-arg constructor) when the generic is parameterised with an abstract class or trait
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E10030: use of a constructor directly on an abstract type is not permitted.
#!ek9 defines module error.e10030.bad defines class Shape as abstract area() as abstract <- rtn as Float? default operator ? Square extends Shape side as Float? default private Square() Square() -> sideLength as Float side: sideLength override area() <- rtn as Float: side * side default operator ? <?- The no-arg constructor is private and never called, but it calls T(). -?> Holder of type T item as T? private Holder() item: T() Holder() -> initial as T item: initial get() <- rtn as T: item default operator ? defines function <?- Shape is abstract: parameterising Holder with it turns the private constructor's T() into Shape(). -?> holdAbstract() square as Shape: Square(3.0) held <- Holder(square) require held?
Fixed: Leave the T property unset in a private no-arg constructor - no T() is needed
#!ek9 defines module error.e10030.good defines class Shape as abstract area() as abstract <- rtn as Float? default operator ? Square extends Shape side as Float? default private Square() Square() -> sideLength as Float side: sideLength override area() <- rtn as Float: side * side default operator ? Holder of type T item as T? default private Holder() Holder() -> initial as T item: initial get() <- rtn as T: item default operator ? defines function holdAbstract() <- rtn as Float? square as Shape: Square(3.0) held <- Holder(square) rtn: held.get().area()
Questions and answers
These Q&A entries show E10030 and its fix: