2

我有这样的课程:

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 eg 创建一个实例var f = make并尝试访问和对象方法 egfOne.getSomething ,我会收到错误消息value One is not a member of type parameter T

4

2 回答 2

3

所以我认为你的问题特别是反射:

this.getClass.getSuperclass.newInstance.asInstanceOf[T]

这里,this是你的实例MetaClass,并且没有特别的理由相信超类this是你想要实例化的类。例如:

class Foo extends NormalClass[Foo]
object Foo extends MetaClass[Foo]

在这种情况下,对象的超类Foo根本不是 a NormalClass,而是java.lang.Object. 结果,它不会有Oneor之类的成员,如果您尝试将其强制转换为Two,您将得到 a 。ClassCastExceptionT

如果您希望该make方法实例化一个 类型的对象T,那么您需要获取 的运行时类T,然后使用它来创建新实例。您可以通过隐式获取 a 来完成此操作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
于 2012-11-06T18:10:40.400 回答
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

如果这不能回答您的问题,请澄清您遇到的问题。

于 2012-11-06T18:09:33.137 回答