在我的代码中,我有类似的东西:
trait MyObj
trait Companion {
type C <: MyObj
}
然后我有几对类和伴随对象,其中伴随扩展Companion,类扩展MyObj并使用String参数定义构造函数。我不能只是创建继承自MyObj的case类,因为我不能让同伴扩展Companion,但我最终在每个companion中重复相同的代码:
class Foo(name: String) extends MyObj
object Foo extends Companion {
type C = Foo
def apply(name: String) = new Foo(name)
// new C(name) works too
}
我想将apply的实现移到Companion trait:
trait Companion {
type C <: MyObj { def this(name: String) }
def apply(name: String) = new C(name)
}
现在继承对象只需要指定C的类型。但这不能编译。有没有办法告诉编译器C必须有一个特定的构造函数,以便我可以调用新的C,而不必手动求助于反射?
答案 0 :(得分:1)
添加ClassTag
或TypeTag
怎么样?它可以是某种反思的中间解决方案:
abstract class Companion[C <: MyObj](implicit ct:ClassTag[C]) {
def apply(name: String):C =
ct.getConstructor(classOf[String]).invoke(Array[Any](name)).asInstanceOf[C]
}
(确切的语法不确定)