2010-02-24 18 views
8

Próbując zdefiniować metody dostępowej dla domyślnej parametru konstruktora, a mianowicie:Jak zdefiniować metodę dostępową dla domyślnego parametru konstruktora?

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

co oczywiście powoduje błąd kompilatora: niejednoznaczne odniesienie do przeciążonej definicji, zarówno wiek metody w klasie Person of type => int i wartości wiek w klasie Osoba typu Int dopasowany oczekiwany typ Int

Czy istnieje sposób na odróżnienie nazwy metody członkowskiej od automatycznie generowanej nazwy wartości elementu?

Oczywiście możliwa jest zmiana nazwy dowolnego identyfikatora, ale czy jest jakiś sposób w tym scenariuszu faktycznego określenia, który identyfikator jest określony?

Odpowiedz

16

Po prostu wstaw "val" przed parametrami konstruktora, które chcesz eksponować jako właściwości instancji.

+0

Dzięki! Sam to wymyśliłem.:-) Ale co jeśli chciałbym zastąpić domyślny akcesor? Chyba nadal będę musiał zmienić nazwę parametru? –

+3

Tak, musisz zmienić nazwę parametru (np. 'Age0'), a następnie zdefiniować accessor' def age = {Math.abs (age0) – retronym

6

Zastosowanie

class Person (val age: Int) 

jeśli chcesz tylko getter lub

class Person (var age: Int) 

jeśli chcesz setter.

3

Powyższe odpowiedzi są świetne w świetle jednolitej zasady dostępu. Jeśli masz lub potrzebujesz programów pobierających i ustawiających w stylu Java, możesz również użyć adnotacji BeanProperty.

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

Spowoduje to następujących metod tworzone:

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

Jeśli zamiast używać BeanProperty dla val zamiast var setter nie zostanie utworzony tylko przebojowa.

Jeszcze jedno zastrzeżenie, metoda ustawiająca nie może być wywołana z wnętrza Scala. Zamiast tego należy użyć standardowej konwencji Scala jednolitego dostępu, aby ustawić wartość.

1

Tylko pod kątem kompletności i rozszerzenia na poprzednie odpowiedzi, jest również technika pokryta here.

Podsumowując, chciałbym zawsze zaczynają się od wartości niezmienne:

class Person (val age: Int) 

Następnie, jeśli dowiedzieć się, trzeba zmutować wartość (lub znasz go z góry), przejdź do:

class Person (var age: Int) 

Potem, jeśli trzeba zweryfikować, czy jakieś inne obliczenia na pobrać lub ustawić, zmienić nazwę zmiennej i budować akcesorów naśladujące oryginalne nazewnictwo, nie trzeba byłaby resztę kodu:

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

Oczywiście, możesz uprościć settera lub gettera, jeśli nie potrzebujesz tam operacji.

Uznanie dla wszystkich innych odpowiedzi, które są rzeczywiście poprawne i pojawiły się znacznie wcześniej.

Powiązane problemy