#scala #constructor #scala-2.9 #traits
#scala #конструктор #scala-2.9 #Трейты
Вопрос:
В 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 { ... }
Комментарии:
1. Почему бы не установить его как a
val
? Вы уже делаете этоDaoism
, так почему бы не сделать это дальшеModuleDao
? Проблема в том, что способ, которым вы объявляете,sessionFactory
фактически является закрытым — никто другой не может его увидеть.
Ответ №1:
Если ваша единственная забота о том, чтобы сделать его значением, — это видимость, вы можете просто сделать значение защищенным следующим образом:
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. Спасибо — в интересах краткости я могу пойти с just
val
и признать, что он общедоступен. Он используется только внутри, поэтому public в этом случае не является слишком общедоступным.