I get the coding in that you basically provide an \"object SomeClass\" and a \"class SomeClass\" and the companion class is the class declaration and the object is a singleton.
Additional to the given answers (and going in the same general direction as jilen), object
s play an important role in Scala's implicit
mechanism, e.g. allowing type-class-like behavior (as known from Haskell):
trait Monoid[T] {
def zero:T
def sum(t1:T, t2:T):T
}
def fold[T](ts:T*)(implicit m:Monoid[T]) = ts.foldLeft(m.zero)(m.sum(_,_))
Now we have a fold
-Function. which "collapses" a number of T
s together, as long as there is an appropriate Monoid
(things that have a neutral element, and can be "added" somehow together) for T
. In order to use this, we need only one instance of a Monoid
for some type T
, the perfect job for an object
:
implicit object StringMonoid extends Monoid[String] {
def zero = ""
def sum(s1:String, s2:String) = s1 + s2
}
Now this works:
println(fold("a","bc","def")) //--> abcdef
So object
s are very useful in their own right.
But wait, there is more! Companion objects can also serve as a kind of "default configuration" when extending their companion class:
trait Config {
def databaseName:String
def userName:String
def password:String
}
object Config extends Config {
def databaseName = "testDB"
def userName = "scott"
def password = "tiger"
}
So on the one hand you have the trait Config
, which can be implemented by the user however she wants, but on the other hand there is a ready made object Config
when you want to go with the default settings.