Use Kotlin Classes

May 22 2024 · Kotlin 1.9.24, Android 14, Kotlin Playground

Lesson 03: Construct Class Instances

Demo

Episode complete

Play next episode

Next
Transcript

How do you know when to use a primary constructor and when a secondary constructor is a better option? For example, you can have default values in the primary constructor and not use the ones you don’t really need.

The Measurements class takes measurements for both 2D and 3D objects.

class Measurements(val length: Int, val width: Int, val depth: Int = 0)

Alternatively, you could use:

class Measurements2(val length: Int, val width: Int, val depth: Int) {
  constructor(length: Int, width: Int) : this(length, width, 0)
}

The use cases for both options are exactly the same. However, a primary constructor with default values is a better option when your class has a set of mandatory properties and some optional properties that can have predefined defaults. It improves code readability by clearly separating essential properties from optional ones.

For example:

class User(val name: String, age: Int = 18)

The User is identified by their name and can probably share their age, but they don’t want you to make a fuss about it. Notice there’s no val or var for the age property.

It’s better to use a secondary constructor when your class needs initialization logic beyond simple property assignment. This logic can include calculations, validation, or delegating to other constructors. Secondary constructors are especially useful when you have multiple ways to create an object of the same class with different data sets.

class Address(val street: String, val city: String) {
  constructor(postalCode: Int) : this(extractStreet(postalCode), extractCity(postalCode)) {
    println("using $street and $city values extracted from $postalCode")
  }

  companion object {
    private fun extractStreet(postalCode: Int): String {
      println("implementation to extract street from postalCode")
      return "street in $postalCode"
    }

    private fun extractCity(postalCode: Int): String {
      println("implementation to extract city from postalCode")
      return "city in $postalCode"
    }
  }
}

fun main() {
  val address = Address(12345)
//implementation to extract street from postalCode
//implementation to extract city from postalCode
//using street in 12345 and city in 12345 values extracted from 12345
}

The Address is reconstructed by the postalCode number, or the street and city can be provided explicitly.

Here are some useful tips:

  • Favor primary constructors with default values for simplicity when possible.
  • Use secondary constructors for complex initialization logic or providing alternative ways to create objects.
  • Keep the number of secondary constructors manageable to avoid code complexity.

Following these simple guidelines, you can effectively use primary and secondary constructors to create well-structured and maintainable Kotlin classes.

See forum comments
Cinema mode Download course materials from Github
Previous: Instruction Next: Conclusion