Extension properties are extensions for classes that allow you to add getters and setters without the ability to add state (backing field). In Java, this is not possible, and the equivalent would be writing utility methods. Historically, to add functionality, static methods or Wrapper objects have had to be used.
Problem: Third-party classes often lack the necessary properties. We want to extend a class concisely and safely without breaking encapsulation.
Solution: In Kotlin, you can declare an extension property, which looks like a regular property but is implemented as functions. This allows for the extension of types to which we do not have access to the source code in a convenient way.
Code example:
val String.firstChar: Char get() = this[0] println("Kotlin".firstChar) // K
Key features:
Can you add a backing field (state) to an extension property?
No, the extension property only computes the value on the fly and cannot hold state.
Can extension properties override properties in inherited classes?
No, extension properties (like extension functions) are inherently static: they cannot be overridden or virtual.
How is an extension property compiled, and why is it not a syntactical equivalent of a regular property?
An extension property actually compiles into a static getter (and/or setter) function. They are not included in the class entities and are only visible in the context of the file where they are declared.
Negative case
A developer tried to add an extension property for storing the state of "visited" in standard Android Views:
var View.isVisited: Boolean get() = ... set(value) { ... } // Error: no storage
Pros:
Cons:
Positive case
An extension property for String was implemented to obtain an extended format:
val String.asTitle: String get() = this.replaceFirstChar { it.uppercase() }
Pros:
Cons: