E06060: a generic type does not support private or protected constructors
What went wrong
A generic type needs public constructors so the type can be parameterised and constructed - and inferred from its arguments - from any context. Protected is never allowed, and neither is a private constructor that takes parameters (type inference uses it). The one exception is the no-argument default constructor: it may be declared 'default private' when the generic has properties of type T with no initial value, so nothing outside can build a partly initialised object.
Worked examples
Compilable examples demonstrating this error and the correct fix:
- ek9 -q 1286 (What does EK9 error E06060 mean on a generic class constr...)
How to fix it
- Remove 'protected' from every constructor of the generic type
- Remove 'private' from any constructor that takes parameters
- Keep 'default private' only on the no-argument constructor, and only where uninitialised T properties make a public one unsafe
Rationale
Generic types are designed for reuse with ANY valid type parameter. A hidden parameterised constructor would stop 'Container(item)' from inferring 'Container of String', defeating the purpose of the generic.
Common causes
- Applying encapsulation patterns from non-generic types
- Wanting to control construction (keep the constructors public and validate with 'require' instead)
- Copy-pasting from non-generic class
See also
Examples
Every example is compiled by the EK9 compiler: the first fails exactly as captioned, the others fix it.
Fails with E06060: a generic type does not support private or protected constructors
#!ek9 defines module error.e06060.bad defines class Box of type T //Protected is never allowed default protected Box() //Private is allowed only on the no-argument constructor default private Box() -> item as T check() -> item as T <- rtn as Boolean: item?
Fixed: Leave a generic type's constructors public (no access modifier)
#!ek9 defines module error.e06060.good defines class Box of type T default Box() default Box() -> item as T check() -> item as T <- rtn as Boolean: item?
Fixed: The no-argument default constructor may be private, when T properties have no initial value
#!ek9 defines module error.e06060.good.private defines class Holder of type T item as T? default private Holder() Holder() -> item as T this.item: item contents() <- rtn as T: item default operator ?
Questions and answers
These Q&A entries show E06060 and its fix: