Skip to content

Commit e028268

Browse files
committed
Tweak the text.
1 parent c53cf2f commit e028268

File tree

1 file changed

+25
-15
lines changed

1 file changed

+25
-15
lines changed

_tour/singleton-objects.md

Lines changed: 25 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@ previous-page: pattern-matching
1313
redirect_from: "/tutorials/tour/singleton-objects.html"
1414
prerequisite-knowledge: classes, methods, private-methods, packages, option
1515
---
16+
An object is a class that has exactly one instance. It is created lazily when it is referenced, like a lazy val.
1617

17-
A singleton object is an instance of a new class. There is exactly one instance of each singleton object. They do not have constructors so they cannot be instantiated.
18+
As a top-level value, an object is a singleton.
1819

20+
As a member of an enclosing class or as a local value, it behaves exactly like a lazy val.
1921
# Defining a singleton object
20-
The simplest form of an object is the keyword `object` and an identifier:
22+
An object is a value. The definition of an object looks like a class, but uses the keyword `object`:
2123
```tut
2224
object Box
2325
```
@@ -30,42 +32,49 @@ object Logger {
3032
def info(message: String): Unit = println(s"INFO: $message")
3133
}
3234
```
33-
The method `info` can be imported from anywhere in the program. Creating utility methods like this is a common use case for singleton objects (however, more sophisticated logging techniques exist). Let's see how to use `info` in another package:
35+
The method `info` can be imported from anywhere in the program. Creating utility methods like this is a common use case for singleton objects.
36+
37+
Let's see how to use `info` in another package:
3438

3539
```
3640
import logging.Logger.info
3741
3842
class Project(name: String, daysToComplete: Int)
3943
40-
val project1 = new Project("TPS Reports", 1)
41-
val project2 = new Project("Website redesign", 5)
42-
info("Created projects") // Prints "INFO: Created projects"
44+
class Test {
45+
val project1 = new Project("TPS Reports", 1)
46+
val project2 = new Project("Website redesign", 5)
47+
info("Created projects") // Prints "INFO: Created projects"
48+
}
4349
```
4450

45-
The `info` method becomes visible in the scope of the package using `import logging.Logger.info`. You could also use `import logging.Logger._` to import everything from Logger.
51+
The `info` method is visible because of the import statement, `import logging.Logger.info`.
4652

47-
Note: If an `object` is nested within another construct such as a class, it is only a singleton in that context. This means there could be an `object NutritionInfo` in the `class Milk` and in the `class OrangeJuice`.
53+
Imports require a "stable path" to the imported symbol, and an object is a stable path.
54+
55+
Note: If an `object` is not top-level but is nested in another class or object, then the object is "path-dependent" like any other member. This means that given two kinds of beverages, `class Milk` and `class OrangeJuice`, a class member `object NutritionInfo` "depends" on the enclosing instance, either milk or orange juice. `milk.NutritionInfo` is entirely distinct from `oj.NutritionInfo`.
4856

4957
## Companion objects
5058

51-
A singleton object with the same name as a class is called a _companion object_. Conversely, the class is the object's companion class. The companion class and object can access each other's private members. Use a companion object for methods and values which are not specific to instances of the companion class.
59+
An object with the same name as a class is called a _companion object_. Conversely, the class is the object's companion class. A companion class or object can access the private members of its companion. Use a companion object for methods and values which are not specific to instances of the companion class.
5260
```
5361
import scala.math._
5462
55-
class Circle(val radius: Double) {
56-
def area: Double = Circle.calculateArea(radius)
63+
case class Circle(radius: Double) {
64+
import Circle._
65+
def area: Double = calculateArea(radius)
5766
}
5867
5968
object Circle {
60-
def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0)
69+
private def calculateArea(radius: Double): Double = Pi * pow(radius, 2.0)
6170
}
6271
6372
val circle1 = new Circle(5.0)
6473
6574
circle1.area
6675
```
6776

68-
The `class Circle` contains the val `radius` which is specific to each instance whereas the `object Circle` contains the method `calculateArea` which is the same for every instance.
77+
The `class Circle` has a member `area` which is specific to each instance, and the singleton `object Circle` has a method `calculateArea` which is available to every instance.
6978

7079
The companion object can also contain factory methods:
7180
```tut
@@ -92,9 +101,10 @@ scalaCenterEmail match {
92101
```
93102
The `object Email` contains a factory `fromString` which creates an `Email` instance from a String. We return it as an `Option[Email]` in case of parsing errors.
94103

95-
Note: If a class or object has a companion, both must be defined in the same file. To define them in the REPL, you must enter `:paste` and then paste in the class and companion object code.
104+
Note: If a class or object has a companion, both must be defined in the same file. To define companions in the REPL, either define them on the same line or enter `:paste` mode.
96105

97106
## Notes for Java programmers ##
98107

99-
`static` is not a keyword in Scala. Instead, all members that would be static, including classes, should go in a singleton object instead.
108+
`static` members in Java are modeled as ordinary members of a companion object in Scala.
109+
100110
When using a companion object from Java code, the members will be defined in a companion class with a `static` modifier. This is called _static forwarding_. It occurs even if you haven't defined a companion class yourself.

0 commit comments

Comments
 (0)