# Objects

The object keyword defines something that looks roughly like a class. However, you can’t create instances of an object—there’s only one. This is sometimes called the Singleton pattern.

An object is a way to combine functions and properties that logically belong together, but this combination either doesn’t require multiple instances, or you want to explicitly prevent multiple instances. You never create an instance of an object—there’s only one and it’s available once the object has been defined:

// Objects/ObjectKeyword.kt
package objects
import atomictest.eq

object JustOne {
  val n = 2
  fun f() = n * 10
  fun g() = this.n * 20   // [1]
}

fun main() {
  // val x = JustOne() // Error
  JustOne.n eq 2
  JustOne.f() eq 20
  JustOne.g() eq 40
}

Here, you can’t say JustOne() to create a new instance of a class JustOne. That’s because the object keyword defines the structure and creates the object at the same time. In addition, it places the elements inside the object’s namespace. If you only want the object to be visible within the current file, you can make it private.

  • [1] The this keyword refers to the single object instance.

You cannot provide a parameter list for an object.

Naming conventions are slightly different when using object. Typically, when we create an instance of a class, we lower-case the first letter of the instance name. When you create an object, however, Kotlin defines the class and creates a single instance of that class. We capitalize the first letter of the object name because it also represents a class.

An object can inherit from a regular class or interface:

// Objects/ObjectInheritance.kt
package objects
import atomictest.eq

open class Paint(val color: String) {
  open fun apply() = "Applying $color"
}

object Acrylic: Paint("Blue") {
  override fun apply() =
    "Acrylic, ${super.apply()}"
}

interface PaintPreparation {
  fun prepare(): String
}

object Prepare: PaintPreparation {
  override fun prepare() = "Scrape"
}

fun main() {
  Prepare.prepare() eq "Scrape"
  Paint("Green").apply() eq "Applying Green"
  Acrylic.apply() eq "Acrylic, Applying Blue"
}

There’s only a single instance of an object, so that instance is shared across all code that uses it. Here’s an object in its own package:

// Objects/GlobalSharing.kt
package objectsharing

object Shared {
  var i: Int = 0
}

We can now use Shared in a different package:

// Objects/Share1.kt
package objectshare1
import objectsharing.Shared

fun f() {
  Shared.i += 5
}

And within a third package:

// Objects/Share2.kt
package objectshare2
import objectsharing.Shared
import objectshare1.f
import atomictest.eq

fun g() {
  Shared.i += 7
}

fun main() {
  f()
  g()
  Shared.i eq 12
}

You can see from the results that Shared is the same object in all packages, which makes sense because object creates a single instance. If you make Shared private, it’s not available in the other files.

objects can’t be placed inside functions, but they can be nested inside other objects or classes (as long as those classes are not themselves nested within other classes):

// Objects/ObjectNesting.kt
package objects
import atomictest.eq

object Outer {
  object Nested {
    val a = "Outer.Nested.a"
  }
}

class HasObject {
  object Nested {
    val a = "HasObject.Nested.a"
  }
}

fun main() {
  Outer.Nested.a eq "Outer.Nested.a"
  HasObject.Nested.a eq "HasObject.Nested.a"
}

There’s another way to put an object inside a class: a companion object, which you’ll see in the [Companion Objects](javascript:void(0)) atom.

Exercises and solutions can be found at www.AtomicKotlin.com.