Companion objects are useful for storing state and methods that are common to all instances of an object but they do not use static methods or fields. They use regular virtual methods which can be overridden through inheritance. Scala truly has nothing static. There are lots of ways you can use this but here's a simple example.
abstract class AnimalCounter
{
var animals = 0
def name: String
def count()
{
animals += 1
println("%d %ss created so far".format(animals, name))
}
}
abstract class Animal
{
def companion: AnimalCounter
companion.count()
}
object Dog extends AnimalCounter
{
val name = "dog"
}
class Dog extends Animal
{
def companion = Dog
}
object Cat extends AnimalCounter
{
val name = "cat"
}
class Cat extends Animal
{
def companion = Cat
}
Which produces this output:
scala> new Dog
1 dogs created so far
scala> new Cat
1 cats created so far
scala> new Dog
2 dogs created so far
scala> new Cat
2 cats created so far