Companion objects are useful for what you would use static methods for in Java...
One very common use is to define an apply()
method in the companion object, which gives users the ability to use MyObject(arg, arg)
as shorthand for new MyObject(arg, arg)
.
Companion objects are also a good place to put things like implicit defs.
I recently have been using companion objects in my akka apps as places to put message case classes which are specific to a supervisor actor and its children, but that I don't necessarily want code outside that subsystem to use directly.
Here's a simple example:
class Complex(real:Double, imag:Double) {
def +(that:Complex):Complex = Complex(this.real + that.real, this.imag + that.imag)
// other useful methods
}
// the companion object
object Complex {
def apply(real:Double, imag:Double) = new Complex(real, imag)
val i = Complex(0, 1)
implicit def fromInt(i:Int) = Complex(i, 0)
}
The normal OOP way to instantiate a new Complex object would be new Complex(x, i)
. In my companion object, I defined the function apply
, to give us a syntactic sugar that allows us to write Complex(x, i)
. apply
is a special function name which is invoked whenever you call an object directly as if it were a function (i.e., Complex()
).
I also have a value called i
which evaluates to Complex(0, 1)
, which gives me a shorthand for using the common complex number i
.
This could be accomplished in Java using a static method like:
public static Complex i() {
return new Complex(0, 1);
}
The companion object essentially gives you a namespace attached to your class name which is not specific to a particular instance of your class.