Skip to content
Table of contents
Companion Object

Companion Object

1 min read #kotlin

Companion Object

If you don’t need to tie member functions to the object, consider for companion object. Regular class elements can access the elements of the companion object, but the companion object elements cannot access the regular class elements.

class WithCompanion {
  companion object {
    val i = 3
    fun doubleIt() = i * 2
  }
  fun tripleIt() = i + doubleIt()
}

fun WithCompanion.Companion.quadrupleIt() = doubleIt() + doubleIt()

val wc = WithCompanion()
wc.tripleIt() // 9
WithCompanion.i // 3
WithCompanion.doubleIt() // 6
WithCompanion.quadrupleIt() // 12
kotlin

As you can see, you can access to member of companion object using class name WithCompanion.i and WithCompanion.doubleIt().

One thing to note is that ONLY one companion object is allowed per class.

Named and Default

One thing to note is that Kotlin assigns the name Companion if you don’t give the companion object a name. And of course, you can still access its elements without using the name.

Single piece of storage

class Computer {
  companion object {
    private var n: Int = 0
  }

  fun increase() = ++n
}

val a = Computer()
val b = Computer()

a.increase() // 1
b.increase() // 2
kotlin

Even if we have two separate objects of Computer, when we call the function increase() for both a and b, the value of n is sharing the same memory. n is a single piece of storage. Likewise, increase() function shows that you can access the private members of the companion object from the surrounding class.

Factory Method Pattern

A common use for a companion object is controlling object creation — this is the Factory Method pattern. Suppose you like to only allow the creation of Lists of Book objects, and not individual Book objects.

class Book
private constructor (private val id: int) {
  override fun toString(): String = "Book#$id"
  companion object Factory {
    fun create(size: Int) =
      List(size) { Book(it) }
  }
}

Book.create(0) // []
Book.create(3) // [Book#0, Book#1, Book#2]
kotlin

Firstly, the Book constructor is private, so the only way for you to create is via the create() factory function.