Kotlin Tutoial
Basics
Control Flow
Array & String
Functions
Collections
OOPs Concept
Exception Handling
Null Safety
Regex & Ranges
Java Interoperability
Miscellaneous
Android
In Kotlin, classes can have properties. A property can be mutable (using var
) or immutable (using val
). Kotlin provides a concise syntax for declaring properties and offers powerful features like custom accessors (getters and setters) to control how properties are read or modified.
You can declare properties directly in the primary constructor or inside the class body:
class Person(val name: String, var age: Int)
In this Person
class, name
is a read-only property, and age
is a mutable property.
By default, Kotlin provides getter methods for all properties and setter methods for var
properties:
val person = Person("Alice", 25) println(person.name) // Calls the default getter for name person.age = 26 // Calls the default setter for age
You can define custom accessors (getter and setter) for properties to add custom logic when getting or setting property values.
Custom Getter:
class Rectangle(val width: Int, val height: Int) { val isSquare: Boolean get() { return width == height } } val rect = Rectangle(10, 20) println(rect.isSquare) // Outputs: false
In the example, the isSquare
property doesn't store any value. It calculates its value every time you access it.
Custom Setter:
For mutable properties (var
), you can provide a custom setter:
class Person(val name: String, age: Int) { var age = age set(value) { if (value > 0) { field = value } else { println("Age can't be negative!") } } } val person = Person("Bob", 30) person.age = -5 // Outputs: Age can't be negative!
In the setter, field
is a special keyword that refers to the backing field of the property. You use it to update the actual stored value.
Kotlin generates a private backing field for properties that need it. This field is accessible using the field
keyword inside the accessors. If you don't use custom accessors that reference the backing field, Kotlin won't create one for the property (like in the case of isSquare
in the above example).
Sometimes you can't initialize a non-null property in the constructor. For such cases, Kotlin provides lateinit
:
class Database { lateinit var connection: Connection fun connect() { connection = Connection() // Initialize the property } } class Connection
With lateinit
, you promise the compiler that you'll initialize the property before accessing it, so it doesn't have to be nullable or immediately initialized.
Kotlin's property system with custom accessors provides a robust mechanism to ensure encapsulation and expressiveness. It allows developers to create clear and safe interfaces while hiding the internal logic and validation associated with property access.
Custom getters and setters in Kotlin: You can define custom getters and setters for properties.
class Person { var age: Int = 0 get() = field + 1 set(value) { field = if (value > 0) value else 0 } }
Working with properties in Kotlin classes: Properties in Kotlin provide a concise syntax for defining fields with custom behavior.
class Circle(var radius: Double) { val diameter: Double get() = 2 * radius }
Delegated properties in Kotlin: Kotlin supports delegated properties, allowing you to delegate the implementation of the property to another class.
class Example { var delegatedValue: String by DelegateClass() }
Property initialization in Kotlin: Properties can be initialized when declared or in the constructor.
class Car(make: String, model: String) { var make: String = make var model: String = model }
Late-initialized properties in Kotlin:
Properties can be marked as lateinit
if they are initialized later (after the object is created).
class Example { lateinit var lateInitializedProperty: String }
Backing fields in Kotlin properties:
Kotlin automatically generates backing fields for properties. You can reference this field using the field
keyword.
var counter: Int = 0 set(value) { if (value > field) { field = value } }
Observable properties in Kotlin:
You can use the observable
delegate to observe changes to a property.
import kotlin.properties.Delegates class Example { var observableProperty: String by Delegates.observable("Initial Value") { _, old, new -> println("Property changed from $old to $new") } }
Computed properties in Kotlin: Properties can be computed on the fly using custom getter logic.
class Circle(var radius: Double) { val area: Double get() = 3.14 * radius * radius }
Custom accessor functions in Kotlin: You can define custom accessor functions for properties to encapsulate behavior.
class Temperature(var celsius: Double) { val fahrenheit: Double get() = celsius * 9 / 5 + 32 }
Property visibility modifiers in Kotlin:
Kotlin allows you to control the visibility of properties using modifiers like private
, protected
, and internal
.
class Example { private var privateProperty: String = "Private" }
Property extension functions in Kotlin: You can define extension functions for properties to add functionality.
val String.isEvenLength: Boolean get() = length % 2 == 0
Immutable properties in Kotlin:
Properties declared with val
are immutable. Once assigned, their values cannot be changed.
class Example { val constantProperty: Int = 42 }