8000 rewrote generic classes tour · MasseGuillaume/scala.github.com@305e2e0 · GitHub
[go: up one dir, main page]

Skip to content

Commit 305e2e0

Browse files
committed
rewrote generic classes tour
1 parent ea9b5ad commit 305e2e0

File tree

1 file changed

+34
-25
lines changed

1 file changed

+34
-25
lines changed

tutorials/tour/_posts/2017-02-13-generic-classes.md

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,40 +9,49 @@ categories: tour
99
num: 18
1010
next-page: variances
1111
previous-page: sequence-comprehensions
12+
assumed-knowledge: classes unified-types
1213
---
14+
Generic classes are classes which take a type as a parameter. They are particularly useful for collection classes.
1315

14-
Like in Java 5 (aka. [JDK 1.5](http://java.sun.com/j2se/1.5/)), Scala has built-in support for classes parameterized with types. Such generic classes are particularly useful for the development of collection classes.
15-
Here is an example which demonstrates this:
16-
16+
## Defining a generic class
17+
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.
1718
```tut
18-
class Stack[T] {
19-
var elems: List[T] = Nil
20-
def push(x: T) { elems = x :: elems }
21-
def top: T = elems.head
22-
def pop() { elems = elems.tail }
19+
class Stack[A] {
20+
private var elements: List[A] = Nil
21+
def push(x: A) { elements = x :: elements }
22+
def peek: A = elements.head
23+
def pop(): A = {
24+
val currentTop = peek
25+
elements = elements.tail
26+
currentTop
27+
}
2328
}
2429
```
30+
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`).
2531

26-
Class `Stack` models imperative (mutable) stacks of an arbitrary element type `T`. The type parameters enforces that only legal elements (that are of type `T`) are pushed onto the stack. Similarly, with type parameters we can express that method `top` will only yield elements of the given type.
27-
28-
Here are some usage examples:
32+
## Usage
2933

30-
```tut
31-
object GenericsTest extends App {
32-
val stack = new Stack[Int]
33-
stack.push(1)
34-
stack.push('a')
35-
println(stack.top)
36-
stack.pop()
37-
println(stack.top)
38-
}
34+
To use a generic class, put the type in the square brackets in place of `A`.
3935
```
36+
val stack = new Stack[Int]
37+
stack.push(1)
38+
stack.push(2)
39+
println(stack.pop) // prints 2
40+
println(stack.pop) // prints 1
41+
```
42+
The instance `stack` can only take Ints. However, if the type argument had subtypes, those could be passed in:
43+
```
44+
class Fruit
45+
class Apple extends Fruit
46+
class Banana extends Fruit
4047
41-
The output of this program will be:
48+
val stack = new Stack[Fruit]
49+
val apple = new Apple
50+
val banana = new Banana
4251
52+
stack.push(apple)
53+
stack.push(banana)
4354
```
44-
97
45-
1
46-
```
55+
Class `Apple` and `Banana` both extend `Fruit` so we can push instances `apple` and `banana` onto the stack of `Fruit`.
4756

48-
_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[T]` is only a subtype of `Stack[S]` if and only if `S = T`. Since this can be quite restrictive, Scala offers a [type parameter annotation mechanism](variances.html) to control the subtyping behavior of generic types._
57+
_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)
0