Extensions improve syntax without changing a class
An extension adds callable syntax for a type but does not modify that type or gain access to its private members. Resolution is based on the declared receiver type, rather than virtual dispatch among extensions.
fun String.topicLabel(): String = trim().ifEmpty { "Untitled" }
val String.wordCount: Int
get() = trim().split(Regex("\\s+")).count { it.isNotEmpty() }
fun main() {
check(" Kotlin basics ".topicLabel() == "Kotlin basics")
check("Kotlin basics".wordCount == 2)
}
An extension property cannot introduce a backing field; it computes or delegates through accessible state. A matching actual member takes precedence over an extension. Broad extensions on Any can pollute completion menus and obscure ownership.
Exercise
Write a List<String>.nonBlankTitles() extension returning a normalized new list. Confirm the original collection is unchanged. Compare a top-level helper with the extension version.
Check: use an extension when reading it as an operation on the receiver makes sense, rather than merely to shorten a call.