Skip to content

Polish translation of Tour of Scala: classes #1209

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jan 19, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
112 changes: 95 additions & 17 deletions _pl/tour/classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,49 +6,127 @@ discourse: false

partof: scala-tour

num: 3
num: 4
language: pl
next-page: traits
previous-page: unified-types
---

Klasy w Scali określają schemat obiektów podczas wykonania programu. Oto przykład definicji klasy `Point`:
Klasy w Scali są wzorcami do tworzenia obiektów.
Klasy mogą zawierać metody, wartości, zmienne, typy, obiekty, cechy i klasy; wszystkie one są nazywane składnikami klasy (_class members_).
Typy, obiekty i cechy zostaną omówione w dalszej części przewodnika.

## Definiowanie klasy

Minimalna definicja klasy składa się ze słowa kluczowego `class` oraz jej identyfikatora.
Nazwy klas powinny zaczynać się z wielkiej litery.

```tut
class User

val user1 = new User
```

Do tworzenia nowych instancji klasy służy słowo kluczowe `new`.
Ponieważ żaden konstruktor nie został zdefiniowany, klasa `User` posiada konstruktor domyślny, który nie przyjmuje żadnych parametrów.
Zazwyczaj jednak definiujemy konstruktor i ciało klasy.
Poniższy przykład przedstawia definicję klasy służącej do reprezentowania punktu.

```tut
class Point(var x: Int, var y: Int) {

def move(dx: Int, dy: Int): Unit = {
x = x + dx
y = y + dy
}

override def toString: String =
"(" + x + ", " + y + ")"
s"($x, $y)"
}

val point1 = new Point(2, 3)
point1.x // 2
println(point1) // wyświetla (2, 3)
```

Klasa `Point` ma cztery składniki: zmienne `x` i `y` oraz metody `move` i `toString`.
W przeciwieństwie do innych języków programowania, główny konstruktor zawiera się w sygnaturze klasy: `(var x: Int, var y: Int)`.
Metoda `move` przyjmuje jako parametry dwie liczby całkowite i zwraca wartość `()` typu `Unit`, która nie niesie ze sobą żadnych informacji.
Odpowiada to słowu kluczowemu `void` w językach Java - podobnych.
Metoda `toString` nie przyjmuje żadnych parametrów, ale zwraca wartość typu `String`.
Ponieważ `toString` nadpisuje metodę `toString` zdefiniowaną w [`AnyRef`](unified-types.html), jest ona dodatkowo oznaczona słowem kluczowym `override`.

## Konstruktory

Konstruktory mogą zawierać parametry opcjonalne - wystarczy dostarczyć wartość domyślną dla takiego parametru.

```tut
class Point(var x: Int = 0, var y: Int = 0)

val origin = new Point // x i y są mają wartość 0
val point1 = new Point(1)
println(point1.x) // wyświetla 1

```

Klasy w Scali są sparametryzowane poprzez argumenty konstruktora. Powyższy kod wymaga podania dwóch argumentów konstruktora: `x` i `y`. Oba parametry są widoczne w zasięgu ciała klasy.
W tej wersji klasy `Point`, `x` oraz `y` mają domyślną wartość `0` - dlatego nie jest wymagane przekazanie żadnych parametrów.
Jednak z powodu tego, że konstruktor jest ewaluowany od lewej do prawej strony, jeżeli chcesz przekazać parametr tylko do argumentu `y`, musisz określić nazwę tego parametru.

```
class Point(var x: Int = 0, var y: Int = 0)
val point2 = new Point(y = 2)
println(point2.y) // wyświetla 2
```

Klasa `Point` zawiera także dwie metody: `move` i `toString`. `move` pobiera dwa argumenty w postaci liczb całkowitych, ale nie zwraca żadnej wartości (zwracany typ `Unit` odpowiada `void` w językach takich jak Java). Z drugiej strony `toString` nie wymaga żadnych parametrów, ale zwraca łańcuch znaków typu `String`. Ponieważ `toString` przesłania predefiniowaną metodę `toString`, jest ona oznaczona słowem kluczowym `override`.
Jest to również dobra praktyka, która zwiększa przejrzystość kodu.

Należy dodać, że w Scali nie jest wymagane podanie słowa kluczowego `return` w celu zwrócenia wartości. Dzięki temu, że każdy blok kodu w Scali jest wyrażeniem, wartością zwracaną przez metodę jest ostatnie wyrażenie w ciele metody. Dodatkowo proste wyrażenia, takie jak zaprezentowane na przykładzie implementacji `toString` nie wymagają podania klamer, zatem można je umieścić bezpośrednio po definicji metody.
## Prywatne składniki oraz składnia getterów i setterów

Instancje klasy można tworzyć w następujący sposób:
Domyślnie wszystkie składniki klasy są publiczne.
Aby ukryć je przed zewnętrznymi klientami (wszystkim co jest poza daną klasą), należy użyć słowa kluczowego `private`.

```tut
object Classes {
def main(args: Array[String]) {
val pt = new Point(1, 2)
println(pt)
pt.move(10, 10)
println(pt)
class Point {
private var _x = 0
private var _y = 0
private val bound = 100

def x = _x
def x_= (newValue: Int): Unit = {
if (newValue < bound) _x = newValue else printWarning
}

def y = _y
def y_= (newValue: Int): Unit = {
if (newValue < bound) _y = newValue else printWarning
}

private def printWarning = println("UWAGA: wartość poza przedziałem")
}

val point1 = new Point
point1.x = 99
point1.y = 101 // wyświetla ostrzeżenie
```

Program definiuje wykonywalną aplikację w postaci [obiektu singleton](singleton-objects.html) z główną metodą `main`. Metoda `main` tworzy nową instancję typu `Point` i zapisuje ją do wartości `pt`. Istotną rzeczą jest to, że wartości zdefiniowane z użyciem słowa kluczowego `val` różnią się od zmiennych określonych przez `var` (jak w klasie `Point` powyżej) tym, że nie dopuszczają aktualizacji ich wartości.
W powyższym przykładnie klasy `Point` dane przechowywane są w prywatnych zmiennych `_x` i `_y`.
Publiczne metody `def x` i `def y` istnieją w celu uzyskania dostępu do prywatnych danych - są to gettery.
Metody `def x_=` i `def y_=` (settery) służą do walidacji oraz ustawiania wartości zmiennych `_x` i `_y`.
Zwróć uwagę na specyficzną składnię dla setterów: posiadają one `_=` dołączone do nazwy, dopiero w dalszej kolejności zdefiniowane są ich parametry.

Parametry głównego konstruktora oznaczone przez `val` i `var` są publiczne.
Ponieważ `val` jest niezmienne, poniższy kod nie jest prawidłowy

```
class Point(val x: Int, val y: Int)
val point = new Point(1, 2)
point.x = 3 // <-- nie kompiluje się
```

Wynik działania programu:
Parametry konstruktora __nie__ zawierające `val` lub `var` są prywatne - widoczne jedynie we wnętrzu klasy.

```
(1, 2)
(11, 12)
class Point(x: Int, y: Int)
val point = new Point(1, 2)
point.x // <-- nie kompiluje się
```