# Constructors

You initialize a new object by passing information to a constructor.

Each object is an isolated world. A program is a collection of objects, so correct initialization of each individual object solves a large part of the initialization problem. Kotlin includes mechanisms to guarantee proper object initialization.

A constructor is like a special member function that initializes a new object. The simplest form of a constructor is a single-line class definition:

// Constructors/Wombat.kt

class Wombat

fun main() {
  val wombat = Wombat()
}

In main(), calling Wombat() creates a Wombat object. If you are coming from another object-oriented language you might expect to see a new keyword used here, but new would be redundant in Kotlin so it was omitted.

You pass information to a constructor using a parameter list, just like a function. Here, the Alien constructor takes a single argument:

// Constructors/Arg.kt

class Alien(name: String) {
  val greeting = "Poor $name!"
}

fun main() {
  val alien = Alien("Mr. Meeseeks")
  println(alien.greeting)
  // alien.name // Error     // [1]
}
/* Output:
Poor Mr. Meeseeks!
*/

Creating an Alien object requires the argument (try it without one). name initializes the greeting property within the constructor, but it is not accessible outside the constructor—try uncommenting line [1].

If you want the constructor parameter to be accessible outside the class body, define it as a var or val in the parameter list:

// Constructors/VisibleArgs.kt

class MutableNameAlien(var name: String)

class FixedNameAlien(val name: String)

fun main() {
  val alien1 =
    MutableNameAlien("Reverse Giraffe")
  val alien2 =
    FixedNameAlien("Krombopolis Michael")

  alien1.name = "Parasite"
  // Can't do this:
  // alien2.name = "Parasite"
}

These class definitions have no explicit class bodies—the bodies are implied.

When name is defined as a var or val, it becomes a property and is thus accessible outside the constructor. val constructor parameters cannot be changed, while var constructor parameters are mutable.

Your class can have numerous constructor parameters:

// Constructors/MultipleArgs.kt

class AlienSpecies(
  val name: String,
  val eyes: Int,
  val hands: Int,
  val legs: Int
) {
  fun describe() =
    "$name with $eyes eyes, " +
      "$hands hands and $legs legs"
}

fun main() {
  val kevin =
    AlienSpecies("Zigerion", 2, 2, 2)
  val mortyJr =
    AlienSpecies("Gazorpian", 2, 6, 2)
  println(kevin.describe())
  println(mortyJr.describe())
}
/* Output:
Zigerion with 2 eyes, 2 hands and 2 legs
Gazorpian with 2 eyes, 6 hands and 2 legs
*/

In [Complex Constructors](javascript:void(0)), you’ll see that constructors can also contain complex initialization logic.

If an object is used when a String is expected, Kotlin calls the object’s toString() member function. If you don’t write one, you still get a default toString():

// Constructors/DisplayAlienSpecies.kt

fun main() {
  val krombopulosMichael =
    AlienSpecies("Gromflomite", 2, 2, 2)
  println(krombopulosMichael)
}
/* Sample output:
AlienSpecies@4d7e1886
*/

The default toString() isn’t very useful—it produces the class name and the physical address of the object (this varies from one program execution to the next). You can define your own toString():

// Constructors/Scientist.kt

class Scientist(val name: String) {
  override fun toString(): String {
    return "Scientist('$name')"
  }
}

fun main() {
  val zeep = Scientist("Zeep Xanflorp")
  println(zeep)
}
/* Output:
Scientist('Zeep Xanflorp')
*/

override is a new keyword for us. It is required here because toString() already has a definition, the one producing the primitive result. override tells Kotlin that yes, we do actually want to replace the default toString() with our own definition. The explicitness of override clarifies the code and prevents mistakes.

A toString() that displays the contents of an object in a convenient form is useful for finding and fixing programming errors. To simplify the process of debugging, IDEs provide debuggers (opens new window) that allow you to observe each step in the execution of a program and to see inside your objects.

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