2012-11-06 59 views
2

我有一類像這樣:使用Scala的反射啓動類的內部對象

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我嘗試訪問和對象方法,例如f.One.getSomething我得到錯誤value One is not a member of type parameter T

回答

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。因此,它不會有像OneTwo這樣的成員,如果您嘗試將其轉換爲T,則會得到ClassCastException

如果您希望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

我不知道是什麼問題。這適用於我:

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] = [email protected] 

scala> res0.One 
res1: res0.One.type = [email protected] 

scala> res0.Two 
res2: res0.Two.type = [email protected] 

如果這沒有回答您的問題,請澄清您遇到的問題。

相關問題