2

私はこのようなクラスを持っています:

class NormalClass[T <: NormalClass[T]] {
  object One
  object Two
}

型指定された特性で上記のクラスの新しいインスタンスを作成できるようにしたいと考えています。次def makeの MetaClass は T のインスタンスを作成しますが、NormalClass に関連付けられた内部オブジェクトがありません。

trait MetaClass[T <: NormalClass[T]] {
  def make:T = this.getClass.getSuperclass.newInstance.asInstanceOf[T]
} 

オブジェクトが欠落している理由と、リフレクションを使用して、そのタイプの内部オブジェクトで新しいクラスを開始するための最良の方法は何かという 2 つの質問があります。

編集:詳細

私が直面している問題は、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はなく、です。その結果、またはのようなメンバーは含まれず、にキャストしようとすると、が得られます。NormalClassjava.lang.ObjectOneTwoClassCastExceptionT

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
于 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 に答える