我有一个这样的课程:
class NormalClass[T <: NormalClass[T]] {
object One
object Two
}
我希望能够在类型特征中创建上述类的新实例。 MetaClass中的以下def make
创建T的实例,但它缺少与NormalClass关联的内部对象。
trait MetaClass[T <: NormalClass[T]] {
def make:T = this.getClass.getSuperclass.newInstance.asInstanceOf[T]
}
我有两个问题,缺少对象的原因是什么,以及使用反射从类型中启动具有内部对象的新类的最佳方法是什么
编辑:更多细节
我面临的问题是,如果我然后使用make创建一个实例,例如var f = make
我尝试访问和对象方法,例如f.One.getSomething我收到错误value One is not a member of type parameter T
。
答案 0 :(得分:3)
所以我认为你的问题尤其是反思:
this.getClass.getSuperclass.newInstance.asInstanceOf[T]
此处,this
是您MetaClass
的实例,并且没有特别的理由相信this
的超类是您要实例化的类。例如:
class Foo extends NormalClass[Foo]
object Foo extends MetaClass[Foo]
在这种情况下,对象Foo
的超类根本不是NormalClass
,而是java.lang.Object
。因此,它不会包含One
或Two
等成员,如果您尝试将其转换为ClassCastException
,则会获得T
。
如果希望make
方法实例化T
类型的对象,则需要获取T
的运行时类,然后使用它来创建新实例。您可以通过隐式获取ClassTag
:
class NormalClass[T <: NormalClass[T]] {
object One
object Two
}
trait MetaClass[T <: NormalClass[T]] {
def make(implicit classTag: scala.reflect.ClassTag[T]): T =
classTag.runtimeClass.newInstance.asInstanceOf[T]
}
// declare a class and an object for creating instances of that class
class Foo extends NormalClass[Foo]
object Foo extends MetaClass[Foo]
// create a new instance of Foo and access its fields
val foo = Foo.make
foo.One
foo.Two
答案 1 :(得分:1)
我不确定问题是什么。这对我有用:
scala> :paste
// Entering paste mode (ctrl-D to finish)
class NormalClass[T <: NormalClass[T]] {
object One
object Two
}
trait MetaClass[T <: NormalClass[T]] {
def make:T = this.getClass.getSuperclass.newInstance.asInstanceOf[T]
}
class X extends NormalClass[X]
// Exiting paste mode, now interpreting.
defined class NormalClass
defined trait MetaClass
defined class X
scala> new X with MetaClass[X]
res0: X with MetaClass[X] = $anon$1@404fe94c
scala> res0.One
res1: res0.One.type = NormalClass$One$@53d9f80
scala> res0.Two
res2: res0.Two.type = NormalClass$Two$@4d0948bd
如果这不能回答您的问题,请澄清您遇到的问题。