Extensions

Extension Functions and Extension Properties

An extension adds a function or property to a type you do not own; inside it, this is the receiver. Unlike patching String.prototype in JavaScript, nothing changes at runtime, and you import an extension where you use it.

Extensions on Double and static dispatchKotlin
fun Double.asPrice() = "$" + "%.2f".format(this)
val Double.isBargain get() = this < 20.0
open class Shape
class Square : Shape()
fun Shape.name() = "Shape"
fun Square.name() = "Square"
fun main() {
  println("${39.5.asPrice()}, bargain: ${39.5.isBargain}")
  val shape: Shape = Square()
  println(shape.name())
}
Output
$39.50, bargain: false
Shape

The last line prints Shape, not Square: extensions are resolved from the declared type, because each one compiles to a static method that takes the receiver as its first parameter (javap shows public static final java.lang.String asPrice(double) in class ExtKt). So an extension property has no backing field, only a getter, and a member with the same signature always wins.

Android is built on extensions: Compose 234 's 16.dp is the extension property Int.dp, Modifier.padding() extends Modifier, and Android KTX adds "https://example.com".toUri().