Skip to content

Polish translation of Tour of Scala: Traits #1219

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
102 changes: 71 additions & 31 deletions _pl/tour/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,52 +6,92 @@ discourse: false

partof: scala-tour

num: 4
num: 5
language: pl
next-page: tuples
previous-page: classes
---

Zbliżone do interfejsów Javy cechy są wykorzystywane do definiowania typów obiektów poprzez określenie sygnatur wspieranych metod. Podobnie jak w Javie 8, Scala pozwala cechom na częściową implementację, tzn. jest możliwe podanie domyślnej implementacji dla niektórych metod. W przeciwieństwie do klas, cechy nie mogą posiadać parametrów konstruktora.
Cechy (Traits) są używane, aby współdzielić interfejsy i pola pomiędzy klasami.
Są bardzo podobne do interfejsów w Javie 8.
Cechy mogą być rozszerzane przez klasy i obiekty, jednak nie można stworzyć instancji danej cechy.
Z tego powodu cechy nie przyjmują parametrów wartości.

Przykład definicji cechy której zadaniem jest określanie podobieństwa z innym obiektem:
## Definiowanie cechy

Minimalna definicja cechy składa się ze słowa kluczowego `trait` oraz identyfikatora.

```tut
trait HairColor
```

Cechy są szczególnie przydatne jako generyczne typy zawierające abstrakcyjne metody.

```tut
trait Similarity {
def isSimilar(x: Any): Boolean
def isNotSimilar(x: Any): Boolean = !isSimilar(x)
trait Iterator[A] {
def hasNext: Boolean
def next(): A
}
```

Powyższa cecha składa się z dwóch metod: `isSimilar` oraz `isNotSimilar`. Mimo że `isSimilar` nie posiada implementacji (odpowiada metodzie abstrakcyjnej w Javie), `isNotSimilar` definiuje konkretną implementację. W ten sposób klasy, które łączą tą cechę, muszą tylko zdefiniować implementacją dla metody `isSimilar`. Zachowanie `isNotSimilar` jest dziedziczone bezpośrednio z tej cechy. Cechy są zazwyczaj łączone z [klasami](classes.html) lub innymi cechami poprzez [kompozycję domieszek](mixin-class-composition.html):

Rozszerzenie cechy `trait Iterator[A]` wymaga wskazania parametru typu `A` oraz zaimplementowania metod `hasNext` i `next`.

## Używanie cech

Aby rozszerzyć cechę należy użyć słowa kluczowego `extends`.
Następnie wymagane jest zaimplementowanie abstrakcyjnych składników danej cechy używając słowa kluczowego `override.`

{% scalafiddle %}
```tut
class Point(xc: Int, yc: Int) extends Similarity {
var x: Int = xc
var y: Int = yc
def isSimilar(obj: Any) =
obj.isInstanceOf[Point] &&
obj.asInstanceOf[Point].x == x
trait Iterator[A] {
def hasNext: Boolean
def next(): A
}

object TraitsTest extends App {
val p1 = new Point(2, 3)
val p2 = new Point(2, 4)
val p3 = new Point(3, 3)
val p4 = new Point(2, 3)
println(p1.isSimilar(p2))
println(p1.isSimilar(p3))
// Metoda isNotSimilar jest zdefiniowana w Similarity
println(p1.isNotSimilar(2))
println(p1.isNotSimilar(p4))
class IntIterator(to: Int) extends Iterator[Int] {
private var current = 0
override def hasNext: Boolean = current < to
override def next(): Int = {
if (hasNext) {
val t = current
current += 1
t
} else 0
}
}
```

Wynik działania programu:

val iterator = new IntIterator(10)
println(iterator.next()) // wyświetli 0
println(iterator.next()) // wyświetli 1
```
true
false
true
false
{% endscalafiddle %}

Klasa `IntIterator` przyjmuje parametr `to` (do) jako ograniczenie górne, oraz rozszerza `extends Iterator[Int]` - co oznacza, że metoda `next` musi zwrócić wartość typu Int.

## Podtyp

Jeżeli w jakimś miejscu wymagana jest cecha pewnego typu, to zamiast niej można użyć jej podtypu.

{% scalafiddle %}
```tut
import scala.collection.mutable.ArrayBuffer

trait Pet {
val name: String
}

class Cat(val name: String) extends Pet
class Dog(val name: String) extends Pet

val dog = new Dog("Harry")
val cat = new Cat("Sally")

val animals = ArrayBuffer.empty[Pet]
animals.append(dog)
animals.append(cat)
animals.foreach(pet => println(pet.name)) // wyświetli Harry Sally
```
{% endscalafiddle %}

Cecha `trait Pet` posiada abstrakcyjne pole `name`, które zostaje zaimplementowane przez klasy `Cat` i `Dog` w ich konstruktorach.
W ostatnim wierszu wywołujemy `pet.name` musi być ono zaimplementowane przez każdy podtyp cechy `Pet`.