@@ -11,31 +11,57 @@ next-page: tuples
11
11
previous-page : classes
12
12
---
13
13
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 เช่นเดียวกับคลาส
16
16
17
17
## การกำหนด trait
18
18
19
19
วิธีที่ง่ายที่สุดในการกำหนด trait คือการประกาศด้วย keyword ` trait ` และ indentifier:
20
20
21
+ {% tabs trait-hair-color %} {% tab 'Scala 2 and 3' for=trait-hair-color %}
22
+
21
23
``` scala mdoc
22
24
trait HairColor
23
25
```
24
26
27
+ {% endtab %} {% endtabs %}
28
+
25
29
trait จะมีประโยชน์อย่างยิ่งด้วยการเป็น generic type และเป็น abstract method
26
30
31
+ {% tabs trait-iterator-definition class=tabs-scala-version %}
32
+
33
+ {% tab 'Scala 2' for=trait-iterator-definition %}
34
+
27
35
``` scala mdoc
28
36
trait Iterator [A ] {
29
37
def hasNext : Boolean
30
38
def next (): A
31
39
}
32
40
```
33
41
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 `
35
57
36
58
## การใช้ traits
37
59
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 %}
39
65
40
66
``` scala mdoc:nest
41
67
trait Iterator [A ] {
@@ -61,12 +87,46 @@ iterator.next() // returns 0
61
87
iterator.next() // returns 1
62
88
```
63
89
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
65
121
66
122
## Subtyping
67
123
68
124
ในเมื่อ trait ที่ให้มานั้น required, subtype ของ trait สามารถถูกใช้แทนที่ได้
69
125
126
+ {% tabs trait-pet-example class=tabs-scala-version %}
127
+
128
+ {% tab 'Scala 2' for=trait-pet-example %}
129
+
70
130
``` scala mdoc
71
131
import scala .collection .mutable .ArrayBuffer
72
132
@@ -83,8 +143,34 @@ val cat = new Cat("Sally")
83
143
val animals = ArrayBuffer .empty[Pet ]
84
144
animals.append(dog)
85
145
animals.append(cat)
86
- animals.foreach(pet => println(pet.name)) // พิมพ์ Harry Sally
146
+ animals.foreach(pet => println(pet.name)) // แสดงค่า Harry Sally
87
147
```
88
148
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