← Back to Kotlin Course | Chapter 10: Extension Functions & Properties | Lesson 2 of 6

Extension Properties

An extension property lets you add a new labeled fact to an existing type, as long as Kotlin can compute it on the fly instead of storing it directly.

Declaring an Extension Property

An extension property adds a computed property to an existing type, written with a custom get() since there is no way to store an actual backing field for it.

Example: Declaring an Extension Property

markup
val String.firstChar: Char
    get() = this[0]

fun main() {
    println("Kotlin".firstChar)
}

Extension Properties Must Be Computed

Because there is no room to add real storage to an existing class, every extension property must derive its value from the receiver each time it is accessed.

Example: Extension Properties Must Be Computed

markup
val List<Int>.average2: Double
    get() = if (this.isEmpty()) 0.0 else this.sum().toDouble() / this.size

fun main() {
    println(listOf(2, 4, 6).average2)
}

Writable Extension Properties

A var extension property can define both get() and set(value), letting it behave like a computed read-write property even though it stores no state of its own directly.

Example: Writable Extension Properties

markup
var StringBuilder.lastChar: Char
    get() = this[this.length - 1]
    set(value) {
        this.setCharAt(this.length - 1, value)
    }

fun main() {
    val sb = StringBuilder("Kotlin!")
    sb.lastChar = '?'
    println(sb)
}

Extension Properties on Custom Types

Extension properties work on your own classes too, which is useful for adding a derived, read-only view of an object's data without modifying the original class.

Example: Extension Properties on Custom Types

markup
data class Rectangle(val width: Double, val height: Double)

val Rectangle.area: Double
    get() = width * height

fun main() {
    val rect = Rectangle(4.0, 5.0)
    println("Area: ${rect.area}")
}
Common Mistakes
  1. Trying to give an extension property a backing field (an initial stored value); extension properties cannot have backing fields, only computed getters (and setters).
  2. Forgetting an extension var property needs both a custom get() and set() since there is no field to default to.
  3. Overusing extension properties for expensive computations, forgetting each access recomputes the value since nothing is cached.
Chapter Summary
  • An extension property is declared as val/var ReceiverType.propertyName: Type get() = ....
  • Extension properties cannot have a backing field -- they must be computed through a custom getter (and setter for var).
  • Like extension functions, extension properties are resolved statically based on the declared type.
  • Extension properties are a clean way to add a derived, read-only fact to an existing type.
🔒

Chapter Quiz — Complete all 6 topics to unlock

0/6 topics done

Complete these topics first:

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.