2010-02-24 2 views
8

Попытки определить акцесор для параметра конструктора по умолчанию, то есть:Как определить метод доступа для параметра конструктора по умолчанию?

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

который, очевидно, приводит к ошибке компилятора: неоднозначной ссылки на перегруженное определение, как метод возраст в классе Person типа => Int и значения возраст в классе Лицо типа Int соответствует ожидаемому типу Int

Есть ли способ в этом контексте различать имя метода-члена и имя сгенерированного автоматически имени элемента?

Конечно, можно изменить имя любого из идентификаторов, но есть ли способ в этом сценарии фактически указать, к какому идентификатору относится?

ответ

16

Просто поместите «val» перед параметрами конструктора, которые вы хотите открыть как свойства экземпляра.

+0

Спасибо! Просто понял это сам.:-) Но что, если я хотел бы переопределить функцию доступа по умолчанию? Думаю, мне все равно нужно переименовать параметр? –

+3

Да, вам нужно переименовать параметр (например, 'age0'), а затем определить accessor' def age = {Math.abs (age0) ' – retronym

6

Использование

class Person (val age: Int) 

, если вы просто хотите, поглотитель или

class Person (var age: Int) 

если вы хотите сеттера.

3

Ответы, приведенные выше, являются превосходными по принципу единого доступа. Если у вас есть или нужны гейтеры и сеттеры стиля Java, вы также можете использовать аннотацию BeanProperty.

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

Это приведет к следующим методам создаются:

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

Если вы вместо того, чтобы использовать BeanProperty для Вала вместо вара, сеттер не будет создан, только геттер.

Еще одно предостережение, метод сеттера не может быть вызван изнутри Scala. Вместо этого вы должны использовать стандартное соглашение Scala для единообразного доступа для установки значения.

1

Для полноты и расширения на предыдущих ответах есть также техника, покрытая here.

Подводя итог, я бы всегда начинается с неизменного значения:

class Person (val age: Int) 

Затем, если вы выясните, что вам нужно мутировать значение (или вы знаете, это заранее), переключиться:

class Person (var age: Int) 

Затем, если вам нужно проверить или сделать некоторые другие вычисления на получить или установить, переименовать переменный и построить аксессор, которые имитируют оригинал именования, нет необходимости реорганизовать остальную часть кода:

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 
    } 
} 

Конечно, вы можете упростить либо сеттер, либо приемник, если вам там не нужны операции.

Превосходство во всех других ответах, которые действительно правильны и пришли намного раньше.

Смежные вопросы