Skip to content

Commit 44d348c

Browse files
committed
update /th/tour/traits page
1 parent 8831eaf commit 44d348c

File tree

1 file changed

+94
-8
lines changed

1 file changed

+94
-8
lines changed

Diff for: _th/tour/traits.md

+94-8
Original file line numberDiff line numberDiff line change
@@ -11,31 +11,57 @@ next-page: tuples
1111
previous-page: classes
1212
---
1313

14-
Trait ใช้เพื่อแชร์ interface และ field ระหว่างคลาส มันจะเหมือนกับ interface ใน Java 8
15-
คลาส และ object สามารถขยาย trait ได้แต่ trait ไม่สามารถ instant เป็น object และไม่สามารถมี parameter ได้
14+
Trait ใช้เพื่อแชร์ interface และ field ระหว่างคลาส มันจะคล้ายกับ interface ใน Java 8
15+
คลาส และ object สามารถ extend trait ได้ แต่ trait ไม่สามารถสร้างเป็น object ได้ ดังนั้น trait จึงไม่สามารถมี parameter เช่นเดียวกับคลาส
1616

1717
## การกำหนด trait
1818

1919
วิธีที่ง่ายที่สุดในการกำหนด trait คือการประกาศด้วย keyword `trait` และ indentifier:
2020

21+
{% tabs trait-hair-color %} {% tab 'Scala 2 and 3' for=trait-hair-color %}
22+
2123
```scala mdoc
2224
trait HairColor
2325
```
2426

27+
{% endtab %} {% endtabs %}
28+
2529
trait จะมีประโยชน์อย่างยิ่งด้วยการเป็น generic type และเป็น abstract method
2630

31+
{% tabs trait-iterator-definition class=tabs-scala-version %}
32+
33+
{% tab 'Scala 2' for=trait-iterator-definition %}
34+
2735
```scala mdoc
2836
trait Iterator[A] {
2937
def hasNext: Boolean
3038
def next(): A
3139
}
3240
```
3341

34-
การขยาย `trait Iterator[A]` ต้องการ type `A` และ implementation ของ method `hasNext` และ `next`
42+
{% endtab %}
43+
44+
{% tab 'Scala 3' for=trait-iterator-definition %}
45+
46+
```scala
47+
trait Iterator[A]:
48+
def hasNext: Boolean
49+
def next(): A
50+
```
51+
52+
{% endtab %}
53+
54+
{% endtabs %}
55+
56+
การขยาย (extend) `trait Iterator[A]` ต้องการ type `A` และ implementation ของ method `hasNext` และ `next`
3557

3658
## การใช้ traits
3759

38-
ใช้ keyword `extends` เพื่อขยาย trait ดังนั้นจะ implement abstract member ใดๆ ของ trait โดยใช้ keyword `override`:
60+
ใช้ keyword `extends` เพื่อขยาย trait จากนั้นให้ implement abstract member ใดๆ ของ trait โดยใช้ keyword `override`:
61+
62+
{% tabs trait-intiterator-definition class=tabs-scala-version %}
63+
64+
{% tab 'Scala 2' for=trait-intiterator-definition %}
3965

4066
```scala mdoc:nest
4167
trait Iterator[A] {
@@ -61,12 +87,46 @@ iterator.next() // returns 0
6187
iterator.next() // returns 1
6288
```
6389

64-
คลาส `IntIterator` นี้รับค่า parameter `to` เป็น upper bound มัน `extends Iterator[Int]` ซึ่งหมายความว่า method `next` จะต้อง return เป็น Int
90+
{% endtab %}
91+
92+
{% tab 'Scala 3' for=trait-intiterator-definition %}
93+
94+
```scala
95+
trait Iterator[A]:
96+
def hasNext: Boolean
97+
def next(): A
98+
99+
class IntIterator(to: Int) extends Iterator[Int]:
100+
private var current = 0
101+
override def hasNext: Boolean = current < to
102+
override def next(): Int =
103+
if hasNext then
104+
val t = current
105+
current += 1
106+
t
107+
else
108+
0
109+
end IntIterator
110+
111+
val iterator = new IntIterator(10)
112+
iterator.next() // returns 0
113+
iterator.next() // returns 1
114+
```
115+
116+
{% endtab %}
117+
118+
{% endtabs %}
119+
120+
คลาส `IntIterator` นี้รับค่า parameter `to` เพื่อกำหนดค่าสูงสุด (upper bound) โดยที่คลาส `IntIterator` ได้ extend จาก `Iterator[Int]` ดังนั้น method `next` จะต้อง return ค่าเป็น Int
65121

66122
## Subtyping
67123

68124
ในเมื่อ trait ที่ให้มานั้น required, subtype ของ trait สามารถถูกใช้แทนที่ได้
69125

126+
{% tabs trait-pet-example class=tabs-scala-version %}
127+
128+
{% tab 'Scala 2' for=trait-pet-example %}
129+
70130
```scala mdoc
71131
import scala.collection.mutable.ArrayBuffer
72132

@@ -83,8 +143,34 @@ val cat = new Cat("Sally")
83143
val animals = ArrayBuffer.empty[Pet]
84144
animals.append(dog)
85145
animals.append(cat)
86-
animals.foreach(pet => println(pet.name)) // พิมพ์ Harry Sally
146+
animals.foreach(pet => println(pet.name)) // แสดงค่า Harry Sally
87147
```
88148

89-
`trait Pet` มี abstract field `name` ซึ่ง implement โดย Cat และ Dog ใน constructor ของมัน
90-
ในบรรทัดสุดท้าย เราเรียก `pet.name` ซึ่งจะต้องถูก implement แล้วใน subtype ใดๆ ของ trait `Pet`
149+
{% endtab %}
150+
151+
{% tab 'Scala 3' for=trait-pet-example %}
152+
153+
```scala
154+
import scala.collection.mutable.ArrayBuffer
155+
156+
trait Pet:
157+
val name: String
158+
159+
class Cat(val name: String) extends Pet
160+
class Dog(val name: String) extends Pet
161+
162+
val dog = Dog("Harry")
163+
val cat = Cat("Sally")
164+
165+
val animals = ArrayBuffer.empty[Pet]
166+
animals.append(dog)
167+
animals.append(cat)
168+
animals.foreach(pet => println(pet.name)) // แสดงค่า Harry Sally
169+
```
170+
171+
{% endtab %}
172+
173+
{% endtabs %}
174+
175+
`trait Pet` มี abstract field `name` ซึ่ง implement ด้วย Cat และ Dog ใน constructor ของมัน
176+
ในบรรทัดสุดท้าย เราเรียกใช้ `pet.name` ซึ่งใน subtype ใดๆ ของ trait `Pet` (ในที่นี้คือ `Cat`, และ `Dog`) ได้ implement field `name` ไว้แล้ว

0 commit comments

Comments
 (0)