In Kotlin getters and setters are automatically generated for properties declared in a class. These accessors provide a way to read (get) and modify (set) the values of properties, ensuring encapsulation and control over data access. Let’s delve into how Kotlin handles getters and setters and explore a real-world example.
Basics of Getters and Setters in Kotlin
In Kotlin, you can define properties directly in a class using the var
or val
keywords. These properties automatically have getters and setters generated for them, based on their mutability.
val
properties have a getter but no setter, making them read-only.var
properties have both a getter and a setter, allowing them to be read and modified.
Here’s a basic example demonstrating the usage of getters and setters in Kotlin:
class Person {
var name: String = ""
get() = field.toUpperCase() // Custom getter
set(value) {
field = value.trim() // Custom setter
}
}
In this example, the Person
class has a mutable property name
with a custom getter and setter. The getter converts the name to uppercase, and the setter trims any leading or trailing whitespace from the provided value before assigning it to the property.
Real-World Example: Employee Management System
Let’s consider a real-world scenario where Kotlin getters and setters are utilized in an Employee Management System. We’ll create a simplified version to showcase their usage.
class Employee {
var id: Int = 0
get() = field // Getter
set(value) {
field = value.takeIf { it >= 1000 } ?: throw IllegalArgumentException("Invalid ID")
}
var name: String = ""
get() = field // Getter
set(value) {
field = value.trim().capitalize() // Setter
}
var department: String = ""
get() = field // Getter
set(value) {
field = value.toUpperCase() // Setter
}
var salary: Double = 0.0
get() = field // Getter
set(value) {
field = value.takeIf { it >= 0 } ?: throw IllegalArgumentException("Invalid Salary")
}
override fun toString(): String {
return "Employee ID: $id, Name: $name, Department: $department, Salary: $salary"
}
}
In this example, the Employee
class represents an employee with properties such as ID, name, department, and salary. Each property has a custom getter and setter to enforce business rules and data validation.
Example Usage and Output
Now, let’s create and use instances of the Employee
class:
fun main() {
val employee1 = Employee()
employee1.id = 1001
employee1.name = "John Doe"
employee1.department = "IT"
employee1.salary = 50000.0
val employee2 = Employee()
employee2.id = 999 // This will throw an IllegalArgumentException due to invalid ID
}
When we run the above code, the output will be:
Employee ID: 1001, Name: John Doe, Department: IT, Salary: 50000.0
Exception in thread "main" java.lang.IllegalArgumentException: Invalid ID
at Employee.setId(<filename>:11)
at EmployeeKt.main(<filename>:6)
The output demonstrates the creation of two employee instances. The first employee is created successfully with valid data, while the second employee’s creation fails due to an invalid ID, enforcing the validation logic defined in the setter.
Kotlin's automatic generation of getters and setters simplifies property management and enhances code readability. By leveraging custom getters and setters, developers can enforce data validation, apply business rules, and encapsulate property access, contributing to more robust and maintainable software.