如何调用Scala抽象类型的构造函数?

Ale*_*ean 8 scala

我正在试图弄清楚如何为Scala抽象类型调用构造函数:

class Journey(val length: Int)
class PlaneJourney(length: Int) extends Journey(length)
class BoatJourney(length: Int) extends Journey(length)

class Port[J <: Journey] {
  def startJourney: J = {
    new J(23) // error: class type required but J found
  }
}
Run Code Online (Sandbox Code Playgroud)

这甚至可行吗?我熟悉Scala清单,但我不清楚它们如何在这里提供帮助.同样,我无法弄清楚如何对伴侣对象的apply()构造函数做同样的事情:

object Journey { def apply() = new Journey(0) }
object PlaneJourney { def apply() = new PlaneJourney(0) }
object BoatJourney { def apply() = new BoatJourney(0) }

class Port[J <: Journey] {
  def startJourney: J = {
    J() // error: not found: value J
  }
}
Run Code Online (Sandbox Code Playgroud)

任何想法都感激不尽!

Kim*_*bel 7

你的类需要一个隐式的构造函数参数来获取Manifest.然后你可以调用erasure来获取Class和调用newInstance,如果有的话,它会反射调用nullary构造函数.

class J[A](implicit m:Manifest[A]) {
  def n = m.erasure.newInstance()
}

new J[Object].n
Run Code Online (Sandbox Code Playgroud)

从Scala 2.10开始,erasure清单中的属性已弃用.def n = m.runtimeClass.newInstance()做同样的事情,但没有警告.


Mor*_*itz 7

没有直接的方法来调用构造函数或仅在给定类型的情况下访问伴随对象.一种解决方案是使用构造给定类型的默认实例的类型类.

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
}
Run Code Online (Sandbox Code Playgroud)

您需要向Default支持创建默认实例的类的所有伴随对象添加隐式定义.