You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
NOTE: I kept the OOP section first, assuming that most readers will be coming from an OOP background.
14
14
{% endcomment %}
15
15
16
-
17
16
Scala supports both functional programming (FP) and object-oriented programming (OOP), as well as a fusion of the two paradigms.
18
17
This section provides a quick overview of data modeling in OOP and FP.
19
18
20
-
21
-
22
19
## OOP Domain Modeling
23
20
24
21
When writing code in an OOP style, your two main tools for data encapsulation are _traits_ and _classes_.
@@ -38,6 +35,29 @@ Later, when you want to create concrete implementations of attributes and behavi
38
35
39
36
As an example of how to use traits as interfaces, here are three traits that define well-organized and modular behaviors for animals like dogs and cats:
40
37
38
+
{% tabs traits class=tabs-scala-version %}
39
+
{% tab 'Scala 2' for=traits %}
40
+
41
+
```scala
42
+
traitSpeaker {
43
+
defspeak():String// has no body, so it’s abstract
44
+
}
45
+
46
+
traitTailWagger {
47
+
defstartTail():Unit= println("tail is wagging")
48
+
defstopTail():Unit= println("tail is stopped")
49
+
}
50
+
51
+
traitRunner {
52
+
defstartRunning():Unit= println("I’m running")
53
+
defstopRunning():Unit= println("Stopped running")
54
+
}
55
+
```
56
+
57
+
{% endtab %}
58
+
59
+
{% tab 'Scala 3' for=traits %}
60
+
41
61
```scala
42
62
traitSpeaker:
43
63
defspeak():String// has no body, so it’s abstract
@@ -51,26 +71,80 @@ trait Runner:
51
71
defstopRunning():Unit= println("Stopped running")
52
72
```
53
73
74
+
{% endtab %}
75
+
{% endtabs %}
76
+
54
77
Given those traits, here’s a `Dog` class that extends all of those traits while providing a behavior for the abstract `speak` method:
If that code makes sense---great, you’re comfortable with traits as interfaces.
85
162
If not, don’t worry, they’re explained in more detail in the [Domain Modeling][data-1] chapter.
86
163
87
-
88
164
### Classes
89
165
90
166
Scala _classes_ are used in OOP-style programming.
91
167
Here’s an example of a class that models a “person.” In OOP fields are typically mutable, so `firstName` and `lastName` are both declared as `var` parameters:
Once you have an enum you can use it in all of the ways you normally use a trait, class, or object:
297
+
{% endtab %}
298
+
{% endtabs %}
299
+
300
+
Once you have an enumeration you can import its members as ordinary values:
301
+
302
+
{% tabs enum_2 class=tabs-scala-version %}
303
+
{% tab 'Scala 2' for=enum_2 %}
304
+
305
+
```scala
306
+
importCrustSize._
307
+
valcurrentCrustSize=Small
308
+
309
+
// enums in a `match` expression
310
+
currentCrustSize match {
311
+
caseSmall=> println("Small crust size")
312
+
caseMedium=> println("Medium crust size")
313
+
caseLarge=> println("Large crust size")
314
+
}
315
+
316
+
// enums in an `if` statement
317
+
if (currentCrustSize ==Small) println("Small crust size")
318
+
```
319
+
320
+
{% endtab %}
321
+
{% tab 'Scala 3' for=enum_2 %}
151
322
152
323
```scala
153
324
importCrustSize.*
@@ -163,20 +334,42 @@ currentCrustSize match
163
334
if currentCrustSize ==Smallthen println("Small crust size")
164
335
```
165
336
166
-
Here’s another example of how to create and use an ADT with Scala:
337
+
{% endtab %}
338
+
{% endtabs %}
339
+
340
+
Here’s another example of how to create a sum type with Scala, this would not be called an enumeration because the `Succ` case has parameters:
341
+
342
+
{% tabs enum_3 class=tabs-scala-version %}
343
+
{% tab 'Scala 2' for=enum_3 %}
344
+
345
+
```scala
346
+
sealedabstractclassNat
347
+
objectNat {
348
+
caseobjectZeroextendsNat
349
+
caseclassSucc(pred: Nat) extendsNat
350
+
}
351
+
```
352
+
353
+
Sum Types are covered in detail in the [Domain Modeling]({% link _overviews/scala3-book/domain-modeling-tools.md %}) section of this book.
354
+
355
+
{% endtab %}
356
+
{% tab 'Scala 3' for=enum_3 %}
167
357
168
358
```scala
169
359
enumNat:
170
360
caseZero
171
361
caseSucc(pred: Nat)
172
362
```
173
363
174
-
Enums are covered in detail in the [Domain Modeling][data-1] section of this book, and in the [Reference documentation]({{ site.scala3ref }}/enums/enums.html).
364
+
Enums are covered in detail in the [Domain Modeling]({% link _overviews/scala3-book/domain-modeling-tools.md %}) section of this book, and in the [Reference documentation]({{ site.scala3ref }}/enums/enums.html).
175
365
366
+
{% endtab %}
367
+
{% endtabs %}
176
368
177
-
### Case classes
369
+
### Product Types
370
+
371
+
A product type is an algebraic data type (ADT) that only has one shape, for example a singleton object, represented in Scala by a `case` object; or an immutable structure with accessible fields, represented by a `case` class.
178
372
179
-
The Scala `case` class lets you model concepts with immutable data structures.
180
373
A `case` class has all of the functionality of a `class`, and also has additional features baked in that make them useful for functional programming.
181
374
When the compiler sees the `case` keyword in front of a `class` it has these effects and benefits:
182
375
@@ -187,7 +380,6 @@ When the compiler sees the `case` keyword in front of a `class` it has these eff
187
380
-`equals` and `hashCode` methods are generated to implement structural equality.
188
381
- A default `toString` method is generated, which is helpful for debugging.
189
382
190
-
191
383
{% comment %}
192
384
NOTE: Julien had a comment about how he decides when to use case classes vs classes. Add something here?
193
385
{% endcomment %}
@@ -196,6 +388,9 @@ You _can_ manually add all of those methods to a class yourself, but since those
196
388
197
389
This code demonstrates several `case` class features:
0 commit comments