2012-05-03 17 views
11

Un ejercicio muy simple de libro de Cay Horstmann «Scala para los impacientes» me mantiene al tanto desconcertante. Es sobre primary, auxiliary y default primary constructores:constructores en Scala (principal/auxiliar/principal predeterminado)

ex 5,10: Considérese la clase

class Employee(val name: String, var salary: Double) { 
    def this() { this("John Q. Public", 0.0) } 
} 

reescritura que utilice campos explícitos y un constructor por defecto primario.

No estoy seguro de lo que se supone que debo hacer. ¿Podrían algunos de ustedes proponer una solución?

Sin embargo, tratando de resolver este ejercicio puede me han hecho consciente de algo que no había notado antes campos constructor acerca primaria y val (como se puede ver, no estoy muy seguro):

I Am correcto si digo que un campo val (como name en la clase anterior Employee) solo se puede inicializar a través del constructor primary y no mediante un auxiliary uno? En este último caso, sería considerado por el compilador como una reasignación a un campo val causando un error.

Al principio pensé en los campos val como un equivalente aproximado de los campos finales en Java, esperando que fuera legal asignarlos por primera vez en cualquier constructor, pero parece que estaba equivocado.

No estoy del todo satisfecho con lo que puede ser solo una suposición, por lo que agradecería que alguien me brinde información más precisa sobre ese punto.

+0

Tuve esta pregunta exacta del mismo ejercicio. Tal vez estoy confundido por lo que el autor quiere decir con "explícito". – vmayer

Respuesta

12

De "Programación en Scala, 2ª edición" en el punto 6.7:

En Scala, cada constructor auxiliar debe invocar a otro constructor de la misma clase que su primera acción. El efecto neto de esta regla es que cada invocación de constructor en Scala finalmente terminará llamando al constructor primario de la clase. El constructor primario es, por lo tanto, el único punto de entrada de una clase.

Por lo tanto, todos los datos para la inicialización de val deben estar en el constructor primario.

su clase con campos explícitos puede ser algo como:

class Employee(n: String = "John Q. Public", s: Double = 0.0) { 
    val name = n 
    var salary = s 
} 

o sin valores de los parámetros por defecto:

class Employee(n: String, s: Double) { 
    def this() = this("John Q. Public", 0.0) 
    val name = n 
    var salary = s 
} 
+0

Gracias por su respuesta. Llegué a una solución bastante cercana a la suya, pero pensé que no cumplía con el objetivo del ejercicio, ya que me imaginé que un "constructor primario predeterminado" era un "constructor no explícitamente declarado sin ningún parámetro". –

11

En realidad, lo que tenía en mente es una versión con una primaria sin argumentos constructor, así:

class Employee { 
    private var _name = "John Q. Public" 
    var salary = 0.0 
    def this(n: String, s: Double) { this(); _name = n; salary = s; } 
    def name = _name  
} 

Claramente, esto es inferior a la definición de los campos en t el constructor primario, que es el punto que quería hacer.

+1

Muchas gracias por tomarse el tiempo para aclarar el objetivo del ejercicio. También un profundo agradecimiento por su libro que es bastante complementario a Martin Odersky y lo hace, más que cualquier otro libro sobre el tema, los primeros pasos en Scala son más simples y agradables. –

Cuestiones relacionadas