2011-10-10 10 views
8

Scalaでは、特性が混在しているクラスの名前付きコンストラクタ引数を参照することは可能ですか? ModuleDaoのコンストラクタ引数は、特性に定義されているvalではないため、以下のコードはコンパイルされません。コンストラクタ引数の前にvalを追加してパブリックにすると、それは特性のものと一致してコンパイルされますが、valとして設定したくないです。形質からのコンストラクタ引数の参照

trait Daoisms { 
    val sessionFactory:SessionFactory 
    protected def session = sessionFactory.getCurrentSession 
} 

class ModuleDao(sessionFactory:SessionFactory) extends Daoisms { 
    def save(module:Module) = session.saveOrUpdate(module) 
} 

/* Compiler error: 
class ModuleDao needs to be abstract, since value sessionFactory in trait Daoisms of type org.hibernate.SessionFactory is not defined */ 

// This works though 
// class ModuleDao(val sessionFactory:SessionFactory) extends Daoisms { ... } 
+0

なぜ 'val'として設定していませんか?あなたはすでに「道教」でこれをやっているので、なぜ「モジュールダオ」でそれをしないのですか?問題は、あなたが宣言している方法では、 'sessionFactory'は実質的に私的です - だれもそれを見ることができないということです。 –

答えて

8

それvalを作るとあなたの唯一の懸念は、視認性の場合は、あなただけのvalはそうのように保護することができます:

scala> trait D { protected val d:Int 
    | def dd = d 
    | } 
defined trait D 

scala> class C(protected val d:Int) extends D 
defined class C 

scala> new C(1) 
res0: C = [email protected] 

scala> res0.d 
<console>:11: error: value d in class C cannot be accessed in C 
Access to protected value d not permitted because 
enclosing class object $iw in object $iw is not a subclass of 
class C in object $iw where target is defined 
       res0.d 
       ^

scala> res0.dd 
res2: Int = 1 
+1

ありがとうございます - 簡潔さのために、私はちょうど 'val'と一緒に行くことができ、それは一般に見えると受け入れることができます。これは内部的にしか使われていないので、この場合公衆はあまり公開されていません。 – Nick

関連する問題