Use the object construct when you need a class with a single instance, or when you want to find a home for miscellaneous values or functions.
Singletons
Scala has no static methods or fields. Instead, you use the object construct. An object defines a single instance of a class with the features that you want. For example,
object Accounts { private var lastNumber = 0 def newUniqueNumber() = { lastNumber += 1; lastNumber } }
When you need a new unique account number in your application, call
Accounts.newUniqueNumber()
The constructor of an object is executed when the object is first used. In our example, the Accounts constructor is executed wit the first call to Accounts.newUniqueNumber() . If an object is never used, its constructor is not executed.
Companion Objects
In Java or C++, you often have a class with both instance methods and static methods. In Scala, you achieve this by having a class and a “companion” object of the same name. For example
class Account { val id = Account.newUniqueNumber() private var balance = 0.0 def deposit(amount: Double) { balance += amount } ... } object Account { // The companion object private var lastNumber = 0 private def newUniqueNumber() = { lastNumber += 1; lastNumber } }
They must be located in the same source file.
Objects Extending a Class or Trait
An object that extends the given class and/or traits has all of the features of the class/traits specified in the object definition. For example, consider a class for undoable actions in a program
abstract class UndoableAction(val description: String) { def undo(): Unit def redo(): Unit }
A useful default is the “do nothing” action. Of course, we only need one of them.
object DoNothingAction extends UndoableAction("Do nothing") { override def undo() {} override def redo() {} }
The DoNothingAction object can be shared across all places that need this default. Like
val actions = Map("open" -> DoNothingAction , "save" -> DoNothingAction , ...)//Open and save not yet implemented
The apply Method
It is common to have objects with an apply method. The apply method is called for expressions of the form Object ( arg1 , ..., argN )
For example, the Array object defines apply methods that allow array creation with expressions such as
Array("Mary", "had", "a", "little", "lamb")
Caution: It is easy to confuse Array(100) and new Array(100) . The first expression calls apply(100) , yielding an Array[Int] with a single element, the integer 100 . The second expression invokes the constructor this(100) . The result is an Array[Nothing] with 100 null elements.
Here is an example of defining an apply method:
class Account private (val id: Int, initialBalance: Double) { private var balance = initialBalance ... } object Account { // The companion object def apply(initialBalance: Double) = new Account(newUniqueNumber(), initialBalance) ... }
Now you can construct an account as val acct = Account(1000.0)
Application Objects
Each Scala program must start with an object’s main method of type Array[String]=>Unit:
object Hello { def main(args: Array[String]) { println("Hello, World!") } }
Instead of providing a main method for your application, you can extend the App trait and place the program code into the constructor body:
object Hello extends App { println("Hello, World!") }
If you need the command-line arguments, you can get them from the args property:
object Hello extends App { if (args.length > 0) println("Hello, " + args(0)) else println("Hello, World!") }
If you invoke the application with the scala.time option set, then the elapsed time is displayed when the program exits.
$ scalac Hello.scala $ scala -Dscala.time Hello Fred Hello, Fred [total 4ms]