Skip to content

Commit 5f67b8d

Browse files
Refresh _ru/tour/mixin-class-composition.md (#2793)
1 parent d47c4a9 commit 5f67b8d

File tree

1 file changed

+131
-11
lines changed

1 file changed

+131
-11
lines changed

_ru/tour/mixin-class-composition.md

Lines changed: 131 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,20 @@
11
---
22
layout: tour
3-
title: Композиция классов с примесями
3+
title: Композиция классов с трейтами
44
partof: scala-tour
55
num: 7
66
language: ru
77
next-page: higher-order-functions
88
previous-page: tuples
99
prerequisite-knowledge: inheritance, traits, abstract-classes, unified-types
1010
---
11+
1112
Примеси (Mixin) - это трейты, которые используются для создания класса.
1213

14+
{% tabs mixin-first-exemple class=tabs-scala-version %}
15+
16+
{% tab 'Scala 2' for=mixin-first-exemple %}
17+
1318
```scala mdoc
1419
abstract class A {
1520
val message: String
@@ -26,21 +31,75 @@ val d = new D
2631
println(d.message) // I'm an instance of class B
2732
println(d.loudMessage) // I'M AN INSTANCE OF CLASS B
2833
```
29-
У класса `D` есть суперкласс `B` и примесь `C`. Классы могут иметь только один суперкласс, но много примесей (используя ключевыое слово `extends` и `with` соответственно). Примеси и суперкласс могут иметь один и тот же супертип.
34+
35+
У класса `D` есть суперкласс `B` и трейт `C`.
36+
Классы могут иметь только один суперкласс, но много трейтов (используя ключевое слово `extends` и `with` соответственно).
37+
Трейты и суперкласс могут иметь один и тот же супертип.
38+
39+
{% endtab %}
40+
41+
{% tab 'Scala 3' for=mixin-first-exemple %}
42+
43+
```scala
44+
abstract class A:
45+
val message: String
46+
class B extends A:
47+
val message = "I'm an instance of class B"
48+
trait C extends A:
49+
def loudMessage = message.toUpperCase()
50+
class D extends B, C
51+
52+
val d = D()
53+
println(d.message) // I'm an instance of class B
54+
println(d.loudMessage) // I'M AN INSTANCE OF CLASS B
55+
```
56+
57+
У класса `D` есть суперкласс `B` и трейт `C`.
58+
Классы могут иметь только один суперкласс, но много трейтов
59+
(используя ключевое слово `extends` и разделитель `,` соответственно).
60+
Трейты и суперкласс могут иметь один и тот же супертип.
61+
62+
{% endtab %}
63+
64+
{% endtabs %}
3065

3166
Теперь давайте рассмотрим более интересный пример, начиная с абстрактного класса:
3267

68+
{% tabs mixin-abstract-iterator class=tabs-scala-version %}
69+
70+
{% tab 'Scala 2' for=mixin-abstract-iterator %}
71+
3372
```scala mdoc
3473
abstract class AbsIterator {
3574
type T
3675
def hasNext: Boolean
3776
def next(): T
3877
}
3978
```
79+
80+
{% endtab %}
81+
82+
{% tab 'Scala 3' for=mixin-abstract-iterator %}
83+
84+
```scala
85+
abstract class AbsIterator:
86+
type T
87+
def hasNext: Boolean
88+
def next(): T
89+
```
90+
91+
{% endtab %}
92+
93+
{% endtabs %}
94+
4095
Класс имеет абстрактный тип `T` и методы стандартного итератора.
4196

4297
Далее создаем конкретную реализацию класса (все абстрактные члены `T`, `hasNext`, и `next` должны быть реализованы):
4398

99+
{% tabs mixin-concrete-string-iterator class=tabs-scala-version %}
100+
101+
{% tab 'Scala 2' for=mixin-concrete-string-iterator %}
102+
44103
```scala mdoc
45104
class StringIterator(s: String) extends AbsIterator {
46105
type T = Char
@@ -53,26 +112,87 @@ class StringIterator(s: String) extends AbsIterator {
53112
}
54113
}
55114
```
115+
116+
{% endtab %}
117+
118+
{% tab 'Scala 3' for=mixin-concrete-string-iterator %}
119+
120+
```scala
121+
class StringIterator(s: String) extends AbsIterator:
122+
type T = Char
123+
private var i = 0
124+
def hasNext = i < s.length
125+
def next() =
126+
val ch = s charAt i
127+
i += 1
128+
ch
129+
```
130+
131+
{% endtab %}
132+
133+
{% endtabs %}
134+
56135
`StringIterator` принимает `String` и может быть использован для обхода по строке (например, чтоб проверить содержит ли строка определенный символ).
57136

58137
Теперь давайте создадим трейт который тоже наследуется от `AbsIterator`.
59138

139+
{% tabs mixin-extended-abstract-iterator class=tabs-scala-version %}
140+
141+
{% tab 'Scala 2' for=mixin-extended-abstract-iterator %}
142+
60143
```scala mdoc
61144
trait RichIterator extends AbsIterator {
62145
def foreach(f: T => Unit): Unit = while (hasNext) f(next())
63146
}
64147
```
65-
У этого трейта реализован метод `foreach` который постоянно вызывает переданную ему функцию `f: T => Unit` на каждом новом элементе (`next()`) до тех пор пока в итераторе содержатся элементы (`while (hasNext)`). Поскольку `RichIterator` это трейт, ему не нужно реализовывать членов абстрактного класса `AbsIterator`.
66148

67-
Мы бы хотели объединить функциональность `StringIterator` и `RichIterator` в один класс.
149+
У этого трейта реализован метод `foreach`, который постоянно вызывает переданную ему функцию `f: T => Unit`
150+
на каждом новом элементе (`next()`) до тех пор пока в итераторе содержатся элементы (`while (hasNext)`).
151+
Поскольку `RichIterator` - это трейт, ему не нужно реализовывать элементы абстрактного класса `AbsIterator`.
152+
153+
{% endtab %}
154+
155+
{% tab 'Scala 3' for=mixin-extended-abstract-iterator %}
156+
157+
```scala
158+
trait RichIterator extends AbsIterator:
159+
def foreach(f: T => Unit): Unit = while hasNext do f(next())
160+
```
161+
162+
У этого трейта реализован метод `foreach`, который постоянно вызывает переданную ему функцию `f: T => Unit`
163+
на каждом новом элементе (`next()`) до тех пор пока в итераторе содержатся элементы (`while hasNext`).
164+
Поскольку `RichIterator` - это трейт, ему не нужно реализовывать элементы абстрактного класса `AbsIterator`.
165+
166+
{% endtab %}
167+
168+
{% endtabs %}
169+
170+
Мы бы хотели объединить функциональность `StringIterator` и `RichIterator` в один класс.
171+
172+
{% tabs mixin-combination-class class=tabs-scala-version %}
173+
174+
{% tab 'Scala 2' for=mixin-combination-class %}
68175

69176
```scala mdoc
70-
object StringIteratorTest extends App {
71-
class RichStringIter extends StringIterator("Scala") with RichIterator
72-
val richStringIter = new RichStringIter
73-
richStringIter foreach println
74-
}
177+
class RichStringIter extends StringIterator("Scala") with RichIterator
178+
val richStringIter = new RichStringIter
179+
richStringIter.foreach(println)
180+
```
181+
182+
{% endtab %}
183+
184+
{% tab 'Scala 3' for=mixin-combination-class %}
185+
186+
```scala
187+
class RichStringIter extends StringIterator("Scala"), RichIterator
188+
val richStringIter = RichStringIter()
189+
richStringIter.foreach(println)
75190
```
76-
Новый класс `RichStringIter` включает `StringIterator` как суперкласс и `RichIterator` как примесь.
77191

78-
Используя только одиночное наследование мы бы не могли добиться того же уровня гибкости.
192+
{% endtab %}
193+
194+
{% endtabs %}
195+
196+
Новый класс `RichStringIter` включает `StringIterator` как суперкласс и `RichIterator` как трейт.
197+
198+
Используя только одиночное наследование мы бы не смогли добиться того же уровня гибкости.

0 commit comments

Comments
 (0)