Kotan Code 枯淡コード

In search of simple, elegant code

Menu Close

Scala Companion Objects

In a single sentence, a Scala companion object is an object with the same name as a companion class in the same file that has access to all of that class’ members, including the private ones.

At first, the power and utility of these companion objects wasn’t really all that clear to me but then I started finding myself using them more and more to the point where I am pretty sure I couldn’t write a Scala app of any decent size without using them.

Let’s take a look at one of the most common uses of a companion object as a place to put factory methods using the apply method:

class BucketOSlime private (val slimeColor:String) {
    // Stuff goes here...
}
object BucketOSlime {
    def apply(color:String):BucketOSlime = new BucketOSlime(color)
}

With this code in place you can now create colorful buckets of slime with a constructor shortcut syntax that lets you leave off the word “new” entirely:

val blueSlime = BucketOSlime("blue")
val whiteSlime = BucketOSlime("white")

The fun (and power) doesn’t stop here. You can use multiple apply methods or a single apply method with pattern matching to return different instances of the same abstract object:

object BucketOSlime {
    def apply(color:String):BucketOSlime = {
        if (color == "blue")
              new BlueBucketOSlime
        else
              new RegularBucketOSlime(color)
    }
}

There are a ton of other ways you can use companion objects. Another common one is to wrap implicits to upgrade or enrich a class (like I’ve done with my MUD recently) so that the implicit doesn’t need to be imported directly.

The more I use Scala, the more I thoroughly enjoy it. I still utterly despise when I see people overloading symbols everywhere so that Scala’s complexity approaches “write once confuse everywhere” status… but with discipline I still think developers can keep Scala syntax clean, concise, and eminently readable.