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 { ... }
Unlike traits in Scala, traits in PHP can have a constructor but it must be declared public (an error will be thrown if is private or protected). Anyway, be cautious when using constructors in traits, though, because it may lead to unintended collisions in the composing classes.
Scala 3 allows traits to have parameters, just like classes have parameters. Arguments to a trait are evaluated immediately before the trait is initialized.
Traits does not contain constructor parameters. When a class inherits one trait, then use extends keyword.
Yes they can, a trait that extends a class puts a restriction on what classes can extend that trait - namely, all classes that mix-in that trait must extend that class .
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With