Skip to content

Commit 62a2a67

Browse files
authored
Add code tabs for _tour/ generic-classes (#2537)
* Add code tabs for _tour/for-comprehensions * Update generic-classes.md * Update generic-classes.md * Update generic-classes.md
1 parent 290876f commit 62a2a67

File tree

1 file changed

+57
-2
lines changed

1 file changed

+57
-2
lines changed

_tour/generic-classes.md

Lines changed: 57 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,14 @@ assumed-knowledge: classes unified-types
1010

1111
redirect_from: "/tutorials/tour/generic-classes.html"
1212
---
13+
1314
Generic classes are classes which take a type as a parameter. They are particularly useful for collection classes.
1415

1516
## Defining a generic class
1617
Generic classes take a type as a parameter within square brackets `[]`. One convention is to use the letter `A` as type parameter identifier, though any parameter name may be used.
18+
19+
{% tabs generic-classes-1 class=tabs-scala-version %}
20+
{% tab 'Scala 2' for=generic-classes-1 %}
1721
```scala mdoc
1822
class Stack[A] {
1923
private var elements: List[A] = Nil
@@ -27,22 +31,56 @@ class Stack[A] {
2731
}
2832
}
2933
```
34+
{% endtab %}
35+
{% tab 'Scala 3' for=generic-classes-1 %}
36+
```scala
37+
class Stack[A]:
38+
private var elements: List[A] = Nil
39+
def push(x: A): Unit =
40+
elements = x :: elements
41+
def peek: A = elements.head
42+
def pop(): A =
43+
val currentTop = peek
44+
elements = elements.tail
45+
currentTop
46+
```
47+
{% endtab %}
48+
{% endtabs %}
49+
3050
This implementation of a `Stack` class takes any type `A` as a parameter. This means the underlying list, `var elements: List[A] = Nil`, can only store elements of type `A`. The procedure `def push` only accepts objects of type `A` (note: `elements = x :: elements` reassigns `elements` to a new list created by prepending `x` to the current `elements`).
3151

3252
`Nil` here is an empty `List` and is not to be confused with `null`.
3353

3454
## Usage
3555

3656
To use a generic class, put the type in the square brackets in place of `A`.
37-
```
57+
58+
{% tabs generic-classes-2 class=tabs-scala-version %}
59+
{% tab 'Scala 2' for=generic-classes-2 %}
60+
```scala mdoc
3861
val stack = new Stack[Int]
3962
stack.push(1)
4063
stack.push(2)
4164
println(stack.pop()) // prints 2
4265
println(stack.pop()) // prints 1
4366
```
44-
The instance `stack` can only take Ints. However, if the type argument had subtypes, those could be passed in:
67+
{% endtab %}
68+
{% tab 'Scala 3' for=generic-classes-2 %}
69+
```scala
70+
val stack = Stack[Int]
71+
stack.push(1)
72+
stack.push(2)
73+
println(stack.pop()) // prints 2
74+
println(stack.pop()) // prints 1
4575
```
76+
{% endtab %}
77+
{% endtabs %}
78+
79+
The instance `stack` can only take Ints. However, if the type argument had subtypes, those could be passed in:
80+
81+
{% tabs generic-classes-3 class=tabs-scala-version %}
82+
{% tab 'Scala 2' for=generic-classes-3 %}
83+
```scala mdoc:nest
4684
class Fruit
4785
class Apple extends Fruit
4886
class Banana extends Fruit
@@ -54,6 +92,23 @@ val banana = new Banana
5492
stack.push(apple)
5593
stack.push(banana)
5694
```
95+
{% endtab %}
96+
{% tab 'Scala 3' for=generic-classes-3 %}
97+
```scala
98+
class Fruit
99+
class Apple extends Fruit
100+
class Banana extends Fruit
101+
102+
val stack = Stack[Fruit]
103+
val apple = Apple()
104+
val banana = Banana()
105+
106+
stack.push(apple)
107+
stack.push(banana)
108+
```
109+
{% endtab %}
110+
{% endtabs %}
111+
57112
Class `Apple` and `Banana` both extend `Fruit` so we can push instances `apple` and `banana` onto the stack of `Fruit`.
58113

59114
_Note: subtyping of generic types is *invariant*. This means that if we have a stack of characters of type `Stack[Char]` then it cannot be used as an integer stack of type `Stack[Int]`. This would be unsound because it would enable us to enter true integers into the character stack. To conclude, `Stack[A]` is only a subtype of `Stack[B]` if and only if `B = A`. Since this can be quite restrictive, Scala offers a [type parameter annotation mechanism](variances.html) to control the subtyping behavior of generic types._

0 commit comments

Comments
 (0)