Objects: Companion Objects

In Scala, a companion object is just an object that declared in the same file as a class that has the same name as the object. With this approach, the class is also known as the companion of the object.

A great thing about this approach is that the companions can access each other's private members (fields and methods). I refer to this is them being married and sharing a joint bank account.

Examples

Example:

// companion class
class Pizza (var crustType: String):
    override def toString = s"Crust type is $crustType"

// companion object
object Pizza:
    // two fields
    val CRUST_TYPE_THIN = "THIN"
    val CRUST_TYPE_THICK = "THICK"
    
    // one method
    def calculatePrice(p: Pizza): Double = 
        // put a fancy pizza-pricing algorithm here
        0.0

Note: Don't define constants using strings like this in the real world.

Usage:

@main def pizzaTest =
    val p = Pizza(Pizza.CRUST_TYPE_THICK)
    println(p)
    println(Pizza.calculatePrice(p))

Another example:

class Circle(val radius: Double):
    import Circle._
    def area: Double = calculateArea(radius)

object Circle:
    // a utility function
    private def calculateArea(radius: Double): Double = Math.PI * radius * radius

Usage:

val c = Circle(3.3)
c.area    // 34.21194399759285

Summary

From what you can see so far, the features and benefits of a companion object are:

  • You put the instance members in the class
  • You put the “static” members in the object
  • The class and object can access each other’s private fields and methods
  • Users of your code can find both of those in the same location (i.e., under the Pizza namespace, in this example)

There’s also another benefit that I’ll show in the next lesson.