In Scala, is it possible for a trait to reference a named constructor argument of the class it is mixed into? The code below doesn't compile because ModuleDao's constructor argument is not a val as defined in the trait. If I add val
before the constructor argument to make it public, it matches up with the one in the trait and it compiles, but I'd prefer not to set it as a 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 { ... }
If your only concern with making it a val is visibility, you can just make the val protected like so:
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 = C@ba2e48
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
精彩评论