2010-02-24 15 views
8

Tratar de definir un método de acceso para el parámetro constructor por defecto, es decir:¿Cómo se define el método de acceso para el parámetro constructor predeterminado?

class Person (age: Int) { 
    def age: Int = this.age 
} 

Lo que obviamente da lugar a un error de compilación: ambigua referencia a la definición sobrecargada, tanto la edad método en la clase Persona de tipo => Int y el valor edad en clase Persona de tipo Int tipo esperado de concordancia Int

¿Existe alguna manera en este contexto para distinguir entre el nombre de método de miembro y el nombre de valor de miembro generado automáticamente?

Por supuesto, es posible cambiar el nombre de cualquiera de los identificadores, pero ¿hay alguna manera en este escenario de especificar realmente a qué identificador se hace referencia?

Respuesta

16

Simplemente ponga "val" delante de los parámetros del constructor que quiera exponer como propiedades de la instancia.

+0

Gracias! Lo descubrí solo.:-) Pero, ¿y si quisiera anular el acceso predeterminado? ¿Supongo que todavía necesitaría cambiar el nombre del parámetro? –

+3

Sí, necesita cambiar el nombre del parámetro (por ejemplo 'age0'), luego defina el acceso' def age = {Math.abs (age0) ' – retronym

6

Uso

class Person (val age: Int) 

si lo que desea es un captador o

class Person (var age: Int) 

si también desea un colocador.

3

Las respuestas anteriores son excelentes con respecto al principio de acceso uniforme. Si tiene o necesita getters y setters de estilo Java, también puede usar la anotación BeanProperty.

class Person(@scala.reflect.BeanProperty var age: Int) 

Esto dará lugar a los siguientes métodos están creando:

def getAge: Int = age 
def setAge(age: Int) = this.age = age 

Si en lugar de utilizar el BeanProperty para un val en lugar de un var, no se creará el organismo, sólo el captador.

Otra advertencia, el método setter no se puede llamar desde dentro de Scala. En su lugar, debe usar la convención estándar de Scala de acceso uniforme para establecer el valor.

1

Para completar y ampliar las respuestas anteriores, también está la técnica cubierta here.

En resumen, yo siempre comenzar con un valor inmutable:

class Person (val age: Int) 

Entonces, si usted averiguar lo que necesita mutar el valor (o usted lo sepa de antemano), cambie a:

class Person (var age: Int) 

Entonces, si es necesario validar o hacer algún otro tipo de cálculo de obtener o establecer, cambiar el nombre de la variable y construir descriptores de acceso que imitan su denominación original, no hay necesidad de refactorizar el resto del código:

class Person(var _age: Int) 
{ 
    def age = 
    { 
     println("age requested") 
     _age 
    } 
    def age_=(newAge: Int) = 
    { 
     assert(newAge > 0) 
     println(s"age changed from ${_age} to $newAge") 
     _age = newAge 
    } 
} 

Por supuesto, puede simplificar setter o getter si no necesita operaciones allí.

Felicita a todas las demás respuestas, que de hecho son correctas y llegaron mucho antes.

Cuestiones relacionadas