从一个特质中引用构造函数的参数

8
在Scala中,一个trait是否可以引用它所混入的类的命名构造函数参数?下面的代码不能编译,因为ModuleDao的构造函数参数不是一个作为trait定义的val。如果我在构造函数参数前添加“val”以使其公开,它将与trait中的构造函数参数匹配,并且编译通过,但我不想将其设置为“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 { ... }

为什么不将它设置为 val 呢?您已经在 Daoism 上这样做了,那么为什么不在 ModuleDao 上这样做呢?问题在于,您声明的方式使 sessionFactory 实际上是私有的 -- 没有其他人可以看到它。 - Daniel C. Sobral
1个回答

8
如果你只关心将其设置为val的可见性,你可以这样将val设置为protected:
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

1
谢谢 - 为了简洁起见,我可能会选择只使用“val”,并接受它是公开可见的。它仅在内部使用,因此在这种情况下,公共不太公共。 - Nick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接