Scala supports static members, but not in the same manner as Java. Scala provides an alternative to this called Singleton Objects. Singleton objects are similar to a normal class, except they can not be instantiated using the new
keyword. Below is a sample singleton class:
object Factorial {
private val cache = Map[Int, Int]()
def getCache = cache
}
Note that we have used object
keyword to define singleton object (instead of 'class' or 'trait'). Since singleton objects can not be instantiated they can not have parameters. Accessing a singleton object looks like this:
Factorial.getCache() //returns the cache
Note that this looks exactly like accessing a static method in a Java class.
In Scala singleton objects may share the name of a corresponding class. In such a scenario the singleton object is referred to as a Companion Object. For instance, below the class Factorial
is defined, and a companion object (also named Factorial
) is defined below it. By convention companion objects are defined in the same file as their companion class.
class Factorial(num : Int) {
def fact(num : Int) : Int = if (num <= 1) 1 else (num * fact(num - 1))
def calculate() : Int = {
if (!Factorial.cache.contains(num)) { // num does not exists in cache
val output = fact(num) // calculate factorial
Factorial.cache += (num -> output) // add new value in cache
}
Factorial.cache(num)
}
}
object Factorial {
private val cache = scala.collection.mutable.Map[Int, Int]()
}
val factfive = new Factorial(5)
factfive.calculate // Calculates the factorial of 5 and stores it
factfive.calculate // uses cache this time
val factfiveagain = new Factorial(5)
factfiveagain.calculate // Also uses cache
In this example we are using a private cache
to store factorial of a number to save calculation time for repeated numbers.
Here object Factorial
is a companion object and class Factorial
is its corresponding companion class. Companion objects and classes can access each other's private
members. In the example above Factorial
class is accessing the private cache
member of it's companion object.
Note that a new instantiation of the class will still utilize the same companion object, so any modification to member variables of that object will carry over.