tags:

views:

166

answers:

3

Trying to define an accessor method for default constructor parameter, i.e.:

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

Which obviously results in a compiler error: ambiguous reference to overloaded definition, both method age in class Person of type => Int and value age in class Person of type Int match expected type Int

Is there a way in this context to distinguish between the member method name and auto-generated member value name?

Of course it's possible to change the name of either identifier, but is there a way in this scenario of actually specifying which identifier is referred to?

+8  A: 

Just put "val" in front of constructor parameters that you want to expose as instance properties.

Randall Schulz
Thanks! Just figured it out myself. :-) But what if I wanted to override the default accessor? I guess I'd still need to rename the parameter?
Totophil
Yes, you need to rename the param (e.g. `age0`), then define the accessor `def age = {Math.abs(age0)`
retronym
+3  A: 

Use

class Person (val age: Int)

if you just want a getter or

class Person (var age: Int)

if you also want a setter.

nuriaion
A: 

The answers above are great wrt the uniform access principle. If you have or need Java style getters and setters you can also use the BeanProperty annotation.

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

This will result in the following methods being created:

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

If you instead use the BeanProperty for a val instead of a var, the setter won't be created, only the getter.

One other caveat, the setter method cannot be called from inside Scala. Instead, you should use the standard Scala convention of uniform access to set the value.

Aaron