2011-10-10 17 views
8

En Scala, ¿es posible que un rasgo haga referencia a un argumento constructor nombrado de la clase en la que se mezcla? El código siguiente no se compila porque el argumento constructor de ModuleDao no es val como se define en el rasgo. Si agrego val antes del argumento constructor para hacerlo público, coincide con el del rasgo y se compila, pero prefiero no configurarlo como val.Referencia a un argumento de constructor de un rasgo

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

¿Por qué no se establece como 'val'? Ya lo estás haciendo en 'Daoism', entonces ¿por qué no hacerlo en' ModuleDao'? El problema es que, como declaras, 'sessionFactory' es efectivamente privado, nadie más puede verlo. –

Respuesta

8

Si su única preocupación con lo que es un val es la visibilidad, sólo puede hacer que el val protegido de este modo:

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

Gracias - en aras de la brevedad, puedo ir con 'val' y aceptar que sea públicamente visible. Solo se usa internamente, por lo que el público no es demasiado público en este caso. – Nick

Cuestiones relacionadas