8000 Refresh _ru\tour\traits.md by artemkorsakov · Pull Request #2790 · scala/docs.scala-lang · GitHub
[go: up one dir, main page]

Skip to content

Refresh _ru\tour\traits.md #2790

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
May 5, 2023
Merged
Show file tree
Hide file tree
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
104 changes: 102 additions & 2 deletions _ru/tour/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,56 @@ prerequisite-knowledge: expressions, classes, generics, objects, companion-objec
Трейты (Traits) используются, чтобы обмениваться между классами информацией о структуре и полях. Они похожи на интерфейсы из Java 8. Классы и объекты могут расширять трейты, но трейты не могут быть созданы и поэтому не имеют параметров.

## Объявление трейта

Минимальное объявление трейта - это просто ключевое слово `trait` и его имя:

{% tabs trait-hair-color %}
{% tab 'Scala 2 и 3' for=trait-hair-color %}

```scala mdoc
trait HairColor
```

{% endtab %}
{% endtabs %}

Трейты наиболее полезны в качестве обобщенного типа с абстрактными методами.

{% tabs trait-iterator-definition class=tabs-scala-version %}

{% tab 'Scala 2' for=trait-iterator-definition %}

```scala mdoc
trait Iterator[A] {
def hasNext: Boolean
def next(): A
}
```

{% endtab %}

{% tab 'Scala 3' for=trait-iterator-definition %}

```scala
trait Iterator[A]:
def hasNext: Boolean
def next(): A
```

{% endtab %}

{% endtabs %}

При наследовании от трейта `Iterator[A]` требует указание типа `A` а также реализация методов `hasNext` и `next`.

## Использование трейтов

Чтобы использовать трейты, необходимо наследовать класс от него, используя ключевое слово `extends`. Затем необходимо реализовать все абстрактные члены трейта, используя ключевое слово `override`:

{% tabs trait-intiterator-definition class=tabs-scala-version %}

{% tab 'Scala 2' for=trait-intiterator-definition %}

```scala mdoc:nest
trait Iterator[A] {
def hasNext: Boolean
Expand All @@ -40,7 +72,7 @@ trait Iterator[A] {
class IntIterator(to: Int) extends Iterator[Int] {
private var current = 0
override def hasNext: Boolean = current < to
override def next(): Int = {
override def next(): Int = {
if (hasNext) {
val t = current
current += 1
Expand All @@ -49,15 +81,51 @@ class IntIterator(to: Int) extends Iterator[Int] {
}
}

val iterator = new IntIterator(10)
iterator.next() // вернет 0
iterator.next() // вернет 1
```

{% endtab %}

{% tab 'Scala 3' for=trait-intiterator-definition %}

```scala
trait Iterator[A]:
def hasNext: Boolean
def next(): A

class IntIterator(to: Int) extends Iterator[Int]:
private var current = 0
override def hasNext: Boolean = current < to
override def next(): Int =
if hasNext then
val t = current
current += 1
t
else
0
end IntIterator

val iterator = new IntIterator(10)
iterator.next() // вернет 0
iterator.next() // вернет 1
```

{% endtab %}

{% endtabs %}

Этот класс `IntIterator` использует параметр `to` в качестве верхней границы. Он наследуется от `Iterator[Int]`, что означает, что метод `next` должен возвращать Int.

## Подтипы
Туда, где требуется определенный тип трейта, мы можем передавать любой наследованный от требуемого трейта класс

Туда, где требуется определенный тип трейта, мы можем передавать любой наследованный от требуемого трейта класс

{% tabs trait-pet-example class=tabs-scala-version %}

{% tab 'Scala 2' for=trait-pet-example %}

```scala mdoc
import scala.collection.mutable.ArrayBuffer

Expand All @@ -76,4 +144,36 @@ animals.append(dog)
animals.append(cat)
animals.foreach(pet => println(pet.name)) // выведет "Harry" и "Sally"
```

{% endtab %}

{% tab 'Scala 3' for=trait-pet-example %}

```scala
import scala.collection.mutable.ArrayBuffer

trait Pet:
val name: String

class Cat(val name: String) extends Pet
class Dog(v 8000 al name: String) extends Pet

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

val animals = ArrayBuffer.empty[Pet]
animals.append(dog)
animals.append(cat)
animals.foreach(pet => println(pet.name)) // выведет "Harry" и "Sally"
```

{% endtab %}

{% endtabs %}

У трейта `Pet` есть абстрактное поле `name`, которое реализовано в классах `Cat` and `Dog`. В последней строке мы вызываем `pet.name`, который должен быть реализован в любом подтипе, унаследованном от трейта `Pet`.

## Дополнительные ресурсы

- Узнайте больше о трейтах в [Scala Book](/scala3/book/domain-modeling-tools.html#traits)
- Использование трейтов для определения [Enum](/scala3/book/domain-modeling-fp.html#modeling-the-data)
4 changes: 2 additions & 2 deletions _tour/traits.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,5 +161,5 @@ The `trait Pet` has an abstract field `name` that gets implemented by Cat and Do

## More resources

* Learn more about traits in the [Scala Book](/overviews/scala-book/traits-intro.html)
* Use traits to define [Enum](/overviews/scala-book/enumerations-pizza-class.html)
* Learn more about traits in the [Scala Book](/scala3/book/domain-modeling-tools.html#traits)
* Use traits to define [Enum](/scala3/book/domain-modeling-fp.html#modeling-the-data)
0