I\'m trying to figure out how to invoke a constructor for a Scala abstract type:
class Journey(val length: Int)
class PlaneJourney(length: Int) extends Journey(l
There is no direct way to invoke the constructor or access the companion object given only a type. One solution would be to use a type class that constructs a default instance of the given type.
trait Default[A] { def default: A }
class Journey(val length: Int)
object Journey {
// Provide the implicit in the companion
implicit def default: Default[Journey] = new Default[Journey] {
def default = new Journey(0)
}
}
class Port[J <: Journey : Default] {
// use the Default[J] instance to create the instance
def startJourney: J = implicitly[Default[J]].default
}
You will need to add an implicit Default
definition to all companion objects of classes that support creation of a default instance.
My inclination is that this cannot be done. I am far from a Scala guru, but my reasoning is this:
The solutions to this problem are handled very nicely in another question, so I will point you there for them rather than repeating here: Abstract Types / Type Parameters in Scala
Your class needs an implicit constructor parameter to get the Manifest
. Then you can call erasure to get the Class
and call newInstance
, which reflectively calls the nullary constructor if there is one.
class J[A](implicit m:Manifest[A]) {
def n = m.erasure.newInstance()
}
new J[Object].n
As of Scala 2.10, the erasure
property in the manifest is deprecated. def n = m.runtimeClass.newInstance()
does the same thing, but without warnings.