Companion Object in Scala

Knoldus Blog Audio
Reading Time: 4 minutes

Companion Object is a singleton object of a class sharing same name and same source file.
The class is called a Companion Class.
For instance, we have a class name Person in Person.scala and an singleton object Person in the same file:

companion object example

In this file the object Person is a companion object and class Person is a companion class.

Benefits of Companion Object

Companion Objects in Scala gives many benefits.
First, companion object and class can access each other private members (fields and methods). The printName method in class Person printing private val name will work as it can access the private field of companion object Person.

companion object accessing private member

Creating new instances without using the new keyword

Companion object also provide a functionality to create new instances of a class without using the new keyword.
Behind the scenes, the apply method defined, has a special meaning for the Scala compiler. This calls the apply method and creates the instance. For Instance:

create instance without new keyword

and during the compilation it changes to:

create instance apply

The apply method act as a factory method, and this syntactic sugar helps in creation of an instance without new keyword.

Using apply Method

To use this functionality, we can create a class Person and a companion object with apply method in Person.scala file.

companion object with apply method

Now, we can create an instance for Person class in the main method.

create instance without new keyword

This will internally call the apply method to create the instance of the class. This also make easy to create a collection like a list of the Person class instances.

Persons list

In this case, when compiler see there is no new keyword. Then, the compiler checks for an apply method, matches the signature of the method.
It uses the apply method to create the instance but if it cannot find an apply method then it gives an compilation error.

Creating multiple constructors

We can also have multiple apply method in the companion object same as multiple auxiliary constructors in the class.

companion object with multiple apply

Here, we have two apply method with different parameters, one with single parameter name, another with two parameters name and age.
These apply method are on the basis of the parameter passed during the instantiation of the class object.

multiple apply object

Adding an unapply method

Same as apply we can have an unapply method, it works exact opposite of apply method.
As apply method helps in construction of an object, unapply method helps in deconstruction of an object.

companion object with unapply method

Here, the unapply method take Person class instance as parameter and return the info of the fields as String in the result.

unapply object

Output:

output unapply method

This will call the unapply method, and returns the name and age as string in result.
The unapply method in companion object, is known as extractor method, because it extracts the fields from the object.

unapply returning different types of result

unapply method can return different type of result based on the result type of the method.

companion object with unapply result map

Now, create object person and call the unapply method.

unapply object

Output:

output unapply result map

We cannot have multiple unapply method in companion object.

Usage of extractor method

Extractor method can help in providing a convenient way to pattern match an object in the match expressions.

You do not have to create apply and unapply method yourself. Instead Scala provide apply and unapply if the class is created as a case class.

Conclusions

  • Companion object and Companion class are declared in the same file.
  • A companion object and companion class can access each others private members.
  • The apply method helps in creating new instance without new keyword.
  • The unapply method helps in deconstructing an instance into individual components.

References