5.5. Parametry klasy
Definicja klasy może zawierać parametry, które definiuje się wymieniając je w nawiasach okrągłych po nazwie klasy. Deklaracje kolejnych parametrów oddziela się od siebie przecinkami. Deklaracja parametru powinna zawierać jego nazwę oraz typ, oddzielone znakiem dwukropka. Deklaracja może opcjonalnie zawierać argument domyślny. Nazwa parametru może opcjonalnie być poprzedzona przedrostkiem val lub var. Plik Parameters1.scala zawiera definicję klasy mającej parametry.
Plik Parameters1.scala: class Parameters1(hello: String, name: String) { def greet = println(hello + " " + name) }
Definicja tej klasy zawiera deklarację dwóch parametrów. Wartości obydwu parametrów mogą być użyte w definicji klasy. Poniższe wyrażenie tworzy instancję tej klasy. Wartości obu parametrów są podane w nawiasach występujących po nazwie klasy.
scala> val a = new Parameters1("Hi", "Peter")
a: Parameters1 = Parameters1@6374ef
scala> a.greet
Hi Peter
Same parametry nie stają się składowymi klasy. Nie można odwołać się do nich z zewnątrz klasy.
scala> a.hello
<console>:12: error: value hello is not a member of Parameters1
a.hello
^
scala> a.name
<console>:12: error: value name is not a member of Parameters1
a.name
^
Jeśli poprzedzimy deklarację parametru słowem val, to taki parametr stanie się składową klasy w podobny sposób, jak wartości zdefiniowane w ciele klasy za pomocą tego słowa kluczowego. Jeśli poprzedzimy deklarację parametru słowem var, to w klasie zostanie zdefiniowana zmienna w podobny sposób, jakby definicja ze słowem kluczowym var znajdowała się w ciele klasy. Definicja klasy, której parametry są poprzedzone słowami kluczowymi val i var, znajduje się w pliku Parameters2.scala.
Plik Parameters2.scala: class Parameters2(val hello: String, var name: String) { def greet = println(hello + " " + name) }
Odwołania z zewnątrz do wartości hello i name instancji tej klasy są możliwe.
scala> val b = new Parameters2("Hi", "Peter")
b: Parameters2 = Parameters2@41a47d
scala> b.hello
res3: String = Hi
scala> b.name
res4: String = Peter
scala> b.name = "Paul"
b.name: String = Paul
scala> b.greet
Hi Paul
Deklaracja parametru może zawierać argument domyślny, wyspecyfikowany po znaku równości. Przykład klasy mającej taką deklarację znajduje się pliku Parameters3.scala.
Plik Parameters3.scala: class Parameters3(name: String, hello: String = "Hello") { def greet = hello + " " + name }
Jeśli parametr zawiera argument domyślny, to może być pominięty przy tworzeniu instancji.
scala> val c = new Parameters3("John", "Hi")
c: Parameters3 = Parameters3@e3a2b2
scala> c.greet
res6: String = Hi John
scala> val d = new Parameters3("Peter")
d: Parameters3 = Parameters3@1553973
scala> d.greet
res7: String = Hello Peter
Przy tworzeniu obiektów można podawać wartości parametrów poprzez argumenty nazwane, co polega na podaniu nazwy parametru, znaku = oraz wartości parametru. Poniższe przykłady pokazują tworzenie instancji klasy Parameters3. W tych przykładach wartości parametrów są podawane poprzez argumenty nazwane. W takim przypadku kolejność podawania wartości parametrów tworzonej instancji nie musi odpowiadać kolejności parametrów w definicji klasy.
scala> val e = new Parameters3(hello = "Welcome", name = "Mike") e: Parameters3 = Parameters3@1efc20d scala> e.greet res8: String = Welcome Mike scala> val f = new Parameters3(name = "Paul", hello = "Hi") f: Parameters3 = Parameters3@1605f2f scala> f.greet res9: String = Hi Paul
Po dwukropku, oddzielającym nazwę parametru od jego typu, można umieścić podwójną strzałkę w prawo (znaki => lub znak ⇒). Tak oznaczone parametry są przekazywane przez nazwę, co powoduje, że ich wartość nie jest obliczana przed utworzeniem instancji klasy, ale za każdym razem, kiedy następuje odwołanie to takiego parametru wewnątrz klasy.
W pliku ClassParametersByName.scala znajduje się definicja klasy, która posiada parametr przekazywany przez nazwę. W tej klasie znajdują się metody, które zawierają odwołania do tego parametru.
Plik ClassParametersByName.scala: class ClassParametersByName(action: => Unit) { def do1 = action def do2 = { action; action } def do3 = { action; action; action } def do4 = { action; action; action; action } }
Każde odwołanie do parametru klasy przekazanego przez nazwę powoduje obliczenie jego wartości. W poniższym przykładzie argumentem klasy ClassParametersByName jest wywołanie metody println. W konsekwencji, każde odwołanie do wartości parametru wewnątrz klasy powoduje wywołanie tej metody.
scala> val g = new ClassParametersByName(println("Hi"))
g: ClassParametersByName = ClassParametersByName@1c64522
scala> g.do1
Hi
scala> g.do2
Hi
Hi
scala> g.do3
Hi
Hi
Hi
scala> g.do4
Hi
Hi
Hi
Hi
Po nazwie typu, w deklaracji ostatniego parametru na liście parametrów klasy, może być umieszczony znak gwiazdki *. Tak zadeklarowany parametr jest nazywany parametrem powtórzonym. Tworząc instancję klasy można podać dowolną liczbę argumentów zgodnych z typem parametru powtórzonego, w tym zero, czyli można pominąć wartość takiego parametru, można podać jedną, dwie lub wiecej jego wartości. Prawdziwym typem parametru powtórzonego zadeklarowanego jako T* jest Seq[T], co oznacza sekwencję wartości typu T. Metoda isEmpty sekwencji zwraca wartość logiczną informującą, czy sekwencja jest pusta. W przypadku niepustych sekwencji metoda head zwraca pierwszy element sekwencji, a metoda tail zwraca sekwencję bez pierwszego elementu.
Plik ClassParametersRepeated.scala: class ClassParametersRepeated(args: String*) { def arguments = argString(args) def argString(as: Seq[String]): String = if (as.isEmpty) "" else as.head + " " + argString(as.tail) }
W pliku ClassParametersRepeated.scala znajduje się definicja klasy, która posiada parametr powtórzony. Metoda arguments zwraca łańcuch znakowy składający się z połączonych spacjami wartości poszczególnych argumentów przekazanych klasie przy tworzeniu jej instancji. Poniższe przykłady pokazują rezultaty działania tej metody na różnych instancjach klasy, utworzonych z różnymi liczbami argumentów.
scala> new ClassParametersRepeated().arguments
res14: String = ""
scala> new ClassParametersRepeated("a").arguments
res15: String = "a "
scala> new ClassParametersRepeated("a","b","c").arguments
res16: String = "a b c "
Klasa może mieć wiele list parametrów. Klasa Parameters4 z pliku Parameters4.scala posiada dwie takie listy.
Plik Parameters4.scala: class Parameters4(hello: String)(name: String) { def greet = println(hello + " " + name) }
W poniższym przykładzie utworzona zostaje instancja tej klasy. W wyrażeniu tworzącym instancję oba parametry klasy podane są w osobnych listach parametrów, a więc są umieszczone w osobnych nawiasach okrągłych.
scala> val g = new Parameters4("Hi")("Peter")
g: Parameters4 = Parameters4@dd323c
scala> g.greet
Hi Peter
![]() | Typ Seq[T] jest opisany dokładniej w rozdziale 18. Nie tylko klasy posiadają parametry. Metody również mogą je posiadać. W przypadku metod również można używać argumentów nazwanych i domyślnych oraz parametrów przekazywanych przez nazwę i parametrów powtórzonych. Metody mogą też posiadać wiele list parametrów. Więcej przykładów dotyczących różnych sposobów przekazywania parametrów czytelnik może znaleźć w rozdziale opisującym metody, czyli w rozdziale 7. |
Plik Parameters1.scala:
class Parameters1(hello: String, name: String) {
def greet = println(hello + " " + name)
}

