Properties and Methods (Getters/Setters) in Kotlin

In Kotlin, properties encapsulate fields with their accessors (getters and setters), streamlining code and enhancing readability. This approach eliminates the need for explicit getter and setter methods, making the codebase cleaner and easier to understand.

1. Why Properties and Methods Matter

Properties in Kotlin provide a concise way to manage data within classes:

2. What Are Properties and Methods?

Property: A property in Kotlin is a combination of a field and its accessors. It is declared using the val (read-only) or var (mutable) keyword.

Getter: A function that retrieves the value of a property. It is automatically provided for val properties and can be customized.

Setter: A function that sets the value of a property. It is automatically provided for var properties and can be customized.

2.1 Default Getters and Setters

class Person {
    var name: String = "John Doe"
    val age: Int = 30
}

In the above example, the name property has both a getter and a setter, while the age property has only a getter because it is declared with val.

2.2 Custom Getters and Setters

Custom getters and setters allow you to add logic when accessing or modifying a property:

class Rectangle(val width: Int, val height: Int) {
    val area: Int
      get() = width * height
}

In this example, the area property calculates its value based on other properties.

2.3 Using Backing Fields

Backing fields are used to store the actual value of a property in memory. You can reference the backing field using the field keyword inside custom setters or getters.

class Person {
    var name: String = "John Doe"
      set(value) {
        // Trim the input before assigning to the backing field
        field = value.trim()
      }
}

Here, field is the backing field for name. The setter ensures any value assigned to name is trimmed of whitespace.

Additional Examples:

class Student {
    var score: Int = 0
      set(value) {
        // Ensure the score is always between 0 and 100
        field = when {
          value < 0 -> 0
          value > 100 -> 100
          else -> value
        }
      }
}

fun main() {
    val student = Student()
    student.score = 150
    println(student.score) // Output: 100
    student.score = -10
    println(student.score) // Output: 0
}

In this example, the backing field field ensures that the score property cannot go below 0 or above 100.

2.4 Controlling Visibility

You can control the visibility of getters and setters independently:

class BankAccount(initialBalance: Int) {
    var balance: Int = initialBalance
      private set
}

In this example, the setter is private, so the balance can only be modified within the class.

3. Common Interview Questions

4. Example Program

fun main() {
    val rectangle = Rectangle(5, 10)
    println("Area: ${rectangle.area}")
}

Output:

Area: 50

5. Key Takeaways