Skip to content

Commit 79fbccd

Browse files
committed
new classes tour
added procedures as prereq
1 parent 0ccd732 commit 79fbccd

File tree

1 file changed

+75
-18
lines changed

1 file changed

+75
-18
lines changed

Diff for: tutorials/tour/_posts/2017-02-13-classes.md

+75-18
Original file line numberDiff line numberDiff line change
@@ -9,46 +9,103 @@ categories: tour
99
num: 4
1010
next-page: traits
1111
previous-page: unified-types
12+
topics: classes
13+
assumed-knowledge: no-return-keyword, type-declaration-syntax, string-interpolation, procedures
1214
---
1315

14-
Classes in Scala are static templates that can be instantiated into many objects at runtime.
15-
Here is a class definition which defines a class `Point`:
16+
Classes in Scala are blueprints for creating objects. They can contain methods,
17+
values, and variables, which are collectively called _members_.
18+
19+
## Defining a class
20+
A minimal class definition is simply the keyword `class` and
21+
an identifier:
22+
```tut
23+
class User
24+
25+
val user1 = new User
26+
```
27+
The keyword `new` is used to create an instance of the class. `User` has an implicit constructor which takes no arguments because no constructor was defined. However, you'll often want a constructor and class body. Here is an example class definition for a point:
1628

1729
```tut
1830
class Point(var x: Int, var y: Int) {
31+
1932
def move(dx: Int, dy: Int): Unit = {
2033
x = x + dx
2134
y = y + dy
2235
}
36+
2337
override def toString: String =
24-
"(" + x + ", " + y + ")"
38+
s"($x, $y)"
2539
}
40+
41+
val point1 = new Point(2, 3)
42+
point1.x // 2
43+
println(point1) // prints (x, y)
2644
```
2745

28-
Classes in Scala are parameterized with constructor arguments. The code above defines two constructor arguments, `x` and `y`; they are both visible in the whole body of the class.
46+
This `Point` class has four members: the variables `x` and `y` and the methods `move` and
47+
`toString`. Unlike many other languages, the primary constructor is in the class signature `(var x: Int, var y: Int)`. The `move` method takes two integer arguments but does not return a value (the return type `Unit` corresponds to `void` in Java-like languages). `toString`, on the other hand, does not take any parameters but returns a `String` value. Since `toString` overrides the inherited `toString` method, it is tagged with the `override` keyword.
48+
49+
## Constructors
50+
51+
Constructors can have optional parameters by providing a default value like so:
2952

30-
The class also includes two methods, `move` and `toString`. `move` takes two integer arguments but does not return a value (the return type `Unit` corresponds to `void` in Java-like languages). `toString`, on the other hand, does not take any parameters but returns a `String` value. Since `toString` overrides the pre-defined `toString` method, it is tagged with the `override` keyword.
53+
```tut
54+
class Point(var x: Int = 0, var y: Int = 0)
3155
32-
Note that in Scala, it isn't necessary to say `return` in order to return a value. The value returned from a method is simply the last value in the method body. In the case of the `toString` method above, the expression after the equals sign is evaluated and returned to the caller.
56+
val origin = new Point // x and y are both set to 0
57+
val point1 = new Point(1)
58+
println(point1.x) // prints 1
3359
34-
Classes are instantiated with the `new` primitive, as follows:
60+
```
3561

62+
In this version of the `Point` class, `x` and `y` have the default value `0` so no arguments are required. However, because the constructor reads arguments left to right, if you just wanted to pass in a `y` value, you would need to name the parameter.
63+
```
64+
class Point(var x: Int = 0, var y: Int = 0)
65+
val point2 = new Point(y=2)
66+
println(point2.y) // prints 2
67+
```
68+
69+
This is also a good practice to enhance clarity.
70+
71+
## Member scope
72+
Members are public by default. Use the `private` access modifier
73+
to hide them from outside of the class.
3674
```tut
37-
object Classes {
38-
def main(args: Array[String]) {
39-
val pt = new Point(1, 2)
40-
println(pt)
41-
pt.move(10, 10)
42-
println(pt)
75+
class Point {
76+
private var _x = 0
77+
private var _y = 0
78+
private val bound = 100
79+
80+
def x = _x
81+
def x_= (newValue: Int): Unit = {
82+
if (newValue < bound) _x = newValue else printWarning
83+
}
84+
85+
def y = _y
86+
def y_= (newValue: Int): Unit = {
87+
if (newValue < bound) _y = newValue else printWarning
4388
}
89+
90+
private def printWarning = println("WARNING: Out of bounds")
4491
}
45-
```
4692
47-
The program defines an executable application Classes in form of a top-level [singleton object](singleton-objects) with a `main` method. The `main` method creates a new `Point` and stores it in value `pt`. Note that values defined with the `val` construct are different from variables defined with the `var` construct (see class `Point` above) in that they do not allow updates; i.e. the value is constant.
93+
val point1 = new Point
94+
point1.x = 99
95+
point1.y = 101 // prints the warning
96+
```
97+
In this version of the `Point` class, the data is stored in private variables `_x` and `_y`. There are methods `def x` and `def y` for accessing the private data. `def x_=` and `def y_=` are for validating and setting the value of `_x` and `_y`. Notice the special syntax for the setters: the method has `_=` appended to the identifier of the getter and the parameters come after.
4898

49-
Here is the output of the program:
99+
Primary constructor parameters with `val` and `var` are public. However, because `val`s are immutable, you can't write the following.
100+
```
101+
class Point(val x: Int, val y: Int)
102+
val point = new Point(1, 2)
103+
val.x = 3 // <-- does not compile
104+
```
50105

106+
Parameters without `val` or `var` are private values, visible only within the class.
51107
```
52-
(1, 2)
53-
(11, 12)
108+
class Point(x: Int, y: Int)
109+
val point = new Point(1, 2)
110+
val.x // <-- does not compile
54111
```

0 commit comments

Comments
 (0)