You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: _pl/tour/traits.md
+71-31
Original file line number
Diff line number
Diff line change
@@ -6,52 +6,92 @@ discourse: false
6
6
7
7
partof: scala-tour
8
8
9
-
num: 4
9
+
num: 5
10
10
language: pl
11
11
next-page: tuples
12
12
previous-page: classes
13
13
---
14
14
15
-
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.
15
+
Cechy (Traits) są używane, aby współdzielić interfejsy i pola pomiędzy klasami.
16
+
Są bardzo podobne do interfejsów w Javie 8.
17
+
Cechy mogą być rozszerzane przez klasy i obiekty, jednak nie można stworzyć instancji danej cechy.
18
+
Z tego powodu cechy nie przyjmują parametrów wartości.
16
19
17
-
Przykład definicji cechy której zadaniem jest określanie podobieństwa z innym obiektem:
20
+
## Definiowanie cechy
21
+
22
+
Minimalna definicja cechy składa się ze słowa kluczowego `trait` oraz identyfikatora.
23
+
24
+
```tut
25
+
trait HairColor
26
+
```
27
+
28
+
Cechy są szczególnie przydatne jako generyczne typy zawierające abstrakcyjne metody.
18
29
19
30
```tut
20
-
trait Similarity {
21
-
def isSimilar(x: Any): Boolean
22
-
def isNotSimilar(x: Any): Boolean = !isSimilar(x)
31
+
trait Iterator[A] {
32
+
def hasNext: Boolean
33
+
def next(): A
23
34
}
24
35
```
25
-
26
-
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):
27
36
37
+
Rozszerzenie cechy `trait Iterator[A]` wymaga wskazania parametru typu `A` oraz zaimplementowania metod `hasNext` i `next`.
38
+
39
+
## Używanie cech
40
+
41
+
Aby rozszerzyć cechę należy użyć słowa kluczowego `extends`.
42
+
Następnie wymagane jest zaimplementowanie abstrakcyjnych składników danej cechy używając słowa kluczowego `override.`
43
+
44
+
{% scalafiddle %}
28
45
```tut
29
-
class Point(xc: Int, yc: Int) extends Similarity {
30
-
var x: Int = xc
31
-
var y: Int = yc
32
-
def isSimilar(obj: Any) =
33
-
obj.isInstanceOf[Point] &&
34
-
obj.asInstanceOf[Point].x == x
46
+
trait Iterator[A] {
47
+
def hasNext: Boolean
48
+
def next(): A
35
49
}
36
50
37
-
object TraitsTest extends App {
38
-
val p1 = new Point(2, 3)
39
-
val p2 = new Point(2, 4)
40
-
val p3 = new Point(3, 3)
41
-
val p4 = new Point(2, 3)
42
-
println(p1.isSimilar(p2))
43
-
println(p1.isSimilar(p3))
44
-
// Metoda isNotSimilar jest zdefiniowana w Similarity
45
-
println(p1.isNotSimilar(2))
46
-
println(p1.isNotSimilar(p4))
51
+
class IntIterator(to: Int) extends Iterator[Int] {
52
+
private var current = 0
53
+
override def hasNext: Boolean = current < to
54
+
override def next(): Int = {
55
+
if (hasNext) {
56
+
val t = current
57
+
current += 1
58
+
t
59
+
} else 0
60
+
}
47
61
}
48
-
```
49
-
50
-
Wynik działania programu:
51
62
63
+
val iterator = new IntIterator(10)
64
+
println(iterator.next()) // wyświetli 0
65
+
println(iterator.next()) // wyświetli 1
52
66
```
53
-
true
54
-
false
55
-
true
56
-
false
67
+
{% endscalafiddle %}
68
+
69
+
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.
70
+
71
+
## Podtyp
72
+
73
+
Jeżeli w jakimś miejscu wymagana jest cecha pewnego typu, to zamiast niej można użyć jej podtypu.
74
+
75
+
{% scalafiddle %}
76
+
```tut
77
+
import scala.collection.mutable.ArrayBuffer
78
+
79
+
trait Pet {
80
+
val name: String
81
+
}
82
+
83
+
class Cat(val name: String) extends Pet
84
+
class Dog(val name: String) extends Pet
85
+
86
+
val dog = new Dog("Harry")
87
+
val cat = new Cat("Sally")
88
+
89
+
val animals = ArrayBuffer.empty[Pet]
90
+
animals.append(dog)
91
+
animals.append(cat)
92
+
animals.foreach(pet => println(pet.name)) // wyświetli Harry Sally
57
93
```
94
+
{% endscalafiddle %}
95
+
96
+
Cecha `trait Pet` posiada abstrakcyjne pole `name`, które zostaje zaimplementowane przez klasy `Cat` i `Dog` w ich konstruktorach.
97
+
W ostatnim wierszu wywołujemy `pet.name` musi być ono zaimplementowane przez każdy podtyp cechy `Pet`.
0 commit comments