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
An object is a class that has exactly one instance. It is created lazily when it is referenced, like a lazy val.
16
17
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.
18
19
20
+
As a member of an enclosing class or as a local value, it behaves exactly like a lazy val.
19
21
# 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`:
21
23
```tut
22
24
object Box
23
25
```
@@ -30,42 +32,49 @@ object Logger {
30
32
def info(message: String): Unit = println(s"INFO: $message")
31
33
}
32
34
```
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:
34
38
35
39
```
36
40
import logging.Logger.info
37
41
38
42
class Project(name: String, daysToComplete: Int)
39
43
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
+
}
43
49
```
44
50
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`.
46
52
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`.
48
56
49
57
## Companion objects
50
58
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.
52
60
```
53
61
import scala.math._
54
62
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)
57
66
}
58
67
59
68
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)
61
70
}
62
71
63
72
val circle1 = new Circle(5.0)
64
73
65
74
circle1.area
66
75
```
67
76
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.
69
78
70
79
The companion object can also contain factory methods:
71
80
```tut
@@ -92,9 +101,10 @@ scalaCenterEmail match {
92
101
```
93
102
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.
94
103
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.
96
105
97
106
## Notes for Java programmers ##
98
107
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
+
100
110
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