@@ -37,6 +37,7 @@ As an example of how to use traits as interfaces, here are three traits that def
37
37
38
38
{% tabs traits class=tabs-scala-version %}
39
39
{% tab 'Scala 2' for=traits %}
40
+
40
41
``` scala
41
42
trait Speaker {
42
43
def speak (): String // has no body, so it’s abstract
@@ -52,9 +53,11 @@ trait Runner {
52
53
def stopRunning (): Unit = println(" Stopped running" )
53
54
}
54
55
```
56
+
55
57
{% endtab %}
56
58
57
59
{% tab 'Scala 3' for=traits %}
60
+
58
61
``` scala
59
62
trait Speaker :
60
63
def speak (): String // has no body, so it’s abstract
@@ -67,25 +70,30 @@ trait Runner:
67
70
def startRunning (): Unit = println(" I’m running" )
68
71
def stopRunning (): Unit = println(" Stopped running" )
69
72
```
73
+
70
74
{% endtab %}
71
75
{% endtabs %}
72
76
73
77
Given those traits, here’s a ` Dog ` class that extends all of those traits while providing a behavior for the abstract ` speak ` method:
74
78
75
79
{% tabs traits-class class=tabs-scala-version %}
76
80
{% tab 'Scala 2' for=traits-class %}
81
+
77
82
``` scala
78
83
class Dog (name : String ) extends Speaker with TailWagger with Runner {
79
84
def speak (): String = " Woof!"
80
85
}
81
86
```
87
+
82
88
{% endtab %}
83
89
84
90
{% tab 'Scala 3' for=traits-class %}
91
+
85
92
``` scala
86
93
class Dog (name : String ) extends Speaker , TailWagger , Runner :
87
94
def speak (): String = " Woof!"
88
95
```
96
+
89
97
{% endtab %}
90
98
{% endtabs %}
91
99
@@ -95,29 +103,48 @@ Similarly, here’s a `Cat` class that implements those same traits while also o
95
103
96
104
{% tabs traits-override class=tabs-scala-version %}
97
105
{% tab 'Scala 2' for=traits-override %}
106
+
98
107
``` scala
99
108
class Cat (name : String ) extends Speaker with TailWagger with Runner {
100
109
def speak (): String = " Meow"
101
110
override def startRunning (): Unit = println(" Yeah ... I don’t run" )
102
111
override def stopRunning (): Unit = println(" No need to stop" )
103
112
}
104
113
```
114
+
105
115
{% endtab %}
106
116
107
117
{% tab 'Scala 3' for=traits-override %}
118
+
108
119
``` scala
109
120
class Cat (name : String ) extends Speaker , TailWagger , Runner :
110
121
def speak (): String = " Meow"
111
122
override def startRunning (): Unit = println(" Yeah ... I don’t run" )
112
123
override def stopRunning (): Unit = println(" No need to stop" )
113
124
```
125
+
114
126
{% endtab %}
115
127
{% endtabs %}
116
128
117
129
These examples show how those classes are used:
118
130
119
131
{% tabs traits-use class=tabs-scala-version %}
120
- {% tab 'Scala 2 and 3' for=traits-use %}
132
+ {% tab 'Scala 2' for=traits-use %}
133
+
134
+ ``` scala
135
+ val d = new Dog (" Rover" )
136
+ println(d.speak()) // prints "Woof!"
137
+
138
+ val c = new Cat (" Morris" )
139
+ println(c.speak()) // "Meow"
140
+ c.startRunning() // "Yeah ... I don’t run"
141
+ c.stopRunning() // "No need to stop"
142
+ ```
143
+
144
+ {% endtab %}
145
+
146
+ {% tab 'Scala 3' for=traits-use %}
147
+
121
148
``` scala
122
149
val d = Dog (" Rover" )
123
150
println(d.speak()) // prints "Woof!"
@@ -127,6 +154,7 @@ println(c.speak()) // "Meow"
127
154
c.startRunning() // "Yeah ... I don’t run"
128
155
c.stopRunning() // "No need to stop"
129
156
```
157
+
130
158
{% endtab %}
131
159
{% endtabs %}
132
160
@@ -140,6 +168,7 @@ Here’s an example of a class that models a “person.” In OOP fields are typ
140
168
141
169
{% tabs class_1 class=tabs-scala-version %}
142
170
{% tab 'Scala 2' for=class_1 %}
171
+
143
172
``` scala
144
173
class Person (var firstName : String , var lastName : String ) {
145
174
def printFullName () = println(s " $firstName $lastName" )
@@ -150,9 +179,11 @@ println(p.firstName) // "John"
150
179
p.lastName = " Legend"
151
180
p.printFullName() // "John Legend"
152
181
```
182
+
153
183
{% endtab %}
154
184
155
185
{% tab 'Scala 3' for=class_1 %}
186
+
156
187
``` scala
157
188
class Person (var firstName : String , var lastName : String ):
158
189
def printFullName () = println(s " $firstName $lastName" )
@@ -162,17 +193,29 @@ println(p.firstName) // "John"
162
193
p.lastName = " Legend"
163
194
p.printFullName() // "John Legend"
164
195
```
196
+
165
197
{% endtab %}
166
198
{% endtabs %}
167
199
168
200
Notice that the class declaration creates a constructor:
169
201
170
202
{% tabs class_2 class=tabs-scala-version %}
171
- {% tab 'Scala 2 and 3' for=class_2 %}
203
+ {% tab 'Scala 2' for=class_2 %}
204
+
205
+ ``` scala
206
+ // this code uses that constructor
207
+ val p = new Person (" John" , " Stephens" )
208
+ ```
209
+
210
+ {% endtab %}
211
+
212
+ {% tab 'Scala 3' for=class_2 %}
213
+
172
214
``` scala
173
215
// this code uses that constructor
174
216
val p = Person (" John" , " Stephens" )
175
217
```
218
+
176
219
{% endtab %}
177
220
{% endtabs %}
178
221
@@ -203,8 +246,9 @@ For instance, a pizza has three main attributes:
203
246
204
247
These are concisely modeled with enums:
205
248
206
- {% tabs enum_1 class=tabs-scala-version %}
207
- {% tab 'Scala 3 only' for=enum_1 %}
249
+ {% tabs enum_1 %}
250
+ {% tab 'Scala 3 Only' for=enum_1 %}
251
+
208
252
``` scala
209
253
enum CrustSize :
210
254
case Small , Medium , Large
@@ -215,13 +259,15 @@ enum CrustType:
215
259
enum Topping :
216
260
case Cheese , Pepperoni , BlackOlives , GreenOlives , Onions
217
261
```
262
+
218
263
{% endtab %}
219
264
{% endtabs %}
220
265
221
266
Once you have an enum you can use it in all of the ways you normally use a trait, class, or object:
222
267
223
- {% tabs enum_2 class=tabs-scala-version %}
224
- {% tab 'Scala 3 only' for=enum_2 %}
268
+ {% tabs enum_2 %}
269
+ {% tab 'Scala 3 Only' for=enum_2 %}
270
+
225
271
``` scala
226
272
import CrustSize .*
227
273
val currentCrustSize = Small
@@ -235,18 +281,21 @@ currentCrustSize match
235
281
// enums in an `if` statement
236
282
if currentCrustSize == Small then println(" Small crust size" )
237
283
```
284
+
238
285
{% endtab %}
239
286
{% endtabs %}
240
287
241
288
Here’s another example of how to create and use an ADT with Scala:
242
289
243
- {% tabs enum_3 class=tabs-scala-version %}
244
- {% tab 'Scala 3 only' for=enum_3 %}
290
+ {% tabs enum_3 %}
291
+ {% tab 'Scala 3 Only' for=enum_3 %}
292
+
245
293
``` scala
246
294
enum Nat :
247
295
case Zero
248
296
case Succ (pred : Nat )
249
297
```
298
+
250
299
{% endtab %}
251
300
{% endtabs %}
252
301
@@ -275,6 +324,7 @@ This code demonstrates several `case` class features:
275
324
276
325
{% tabs case-class class=tabs-scala-version %}
277
326
{% tab 'Scala 2 and 3' for=case-class %}
327
+
278
328
``` scala
279
329
// define a case class
280
330
case class Person (
@@ -297,6 +347,7 @@ p.name = "Joe" // error: can’t reassign a val field
297
347
val p2 = p.copy(name = " Elton John" )
298
348
p2 // : Person = Person(Elton John,Singer)
299
349
```
350
+
300
351
{% endtab %}
301
352
{% endtabs %}
302
353
0 commit comments