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

Extension Functions

An extension function lets you bolt a brand-new ability onto a type you don't even own, like adding a new button to someone else's remote control.

Declaring an Extension Function

An extension function is written as fun Type.name(...), letting you call value.name(...) as if name were a real member of Type, even though Type's own source code was never touched.

Example: Declaring an Extension Function

markup
fun String.shout(): String = this.toUpperCase() + "!"

fun main() {
    println("hello".shout())
}

Using this Inside an Extension

Within an extension function's body, this refers to the receiver -- the value the extension was called on -- and can usually be omitted just like in a regular member function.

Example: Using this Inside an Extension

markup
fun Int.isEven(): Boolean = this % 2 == 0

fun main() {
    println("4 is even: ${4.isEven()}")
    println("7 is even: ${7.isEven()}")
}

Extensions on Standard Library Types

Extension functions are especially handy for adding convenient behavior to types you cannot modify directly, including standard library or third-party classes.

Example: Extensions on Standard Library Types

markup
fun List<Int>.secondOrNull(): Int? = if (this.size >= 2) this[1] else null

fun main() {
    println(listOf(10, 20, 30).secondOrNull())
    println(listOf(10).secondOrNull())
}

Static Resolution of Extensions

Which extension function gets called is decided at compile time based on the declared (static) type of the expression, not the object's actual runtime type -- unlike overridden member functions.

Note: This prints "An animal" because animal is statically typed as Animal, even though it holds a Dog at runtime.

Example: Static Resolution of Extensions

markup
open class Animal
class Dog : Animal()

fun Animal.describe() = "An animal"
fun Dog.describe() = "A dog"

fun main() {
    val animal: Animal = Dog()
    println(animal.describe())
}
Common Mistakes
  1. Assuming an extension function actually modifies the original class; it is resolved statically and does not change the class itself in any way.
  2. Expecting extension functions to be polymorphic like member functions; which extension gets called is determined by the declared type at compile time, not the runtime type.
  3. Forgetting to import an extension function declared in another package, since it must be imported just like any other top-level function.
Chapter Summary
  • An extension function is declared as fun ReceiverType.functionName(...) { ... }, adding a callable method to an existing type.
  • Inside the extension, this refers to the receiver instance the function was called on.
  • Extension functions are resolved statically based on the declared type, not dynamically based on the actual runtime type.
  • Extension functions do not actually modify the original class; they are just syntactic sugar for a top-level function call.
🔒

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.