Extension Functions
Kotlin is a modern, concise language that lets you add new functions and properties to existing types — even ones you didn't write — without inheritance, through extension functions.
Learn Extension Functions in our free Kotlin course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick reference.
Part of the free Kotlin course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
By the end of this lesson you'll write extension functions and properties, use the this receiver, and understand how they're resolved.
What You'll Learn in This Lesson
1️⃣ Extension Functions
An extension function is declared as fun ReceiverType.name(...) . Inside, this refers to the value it's called on (the receiver). You can extend any type — your own classes or library types like String and Int .
These read as if the methods always existed on the type — that's the whole appeal. Your IDE even lists them in autocomplete.
2️⃣ Extension Properties and Nullable Receivers
You can also add extension properties (computed, since they can't store state) and extend collections or even nullable types — letting an extension handle null itself.
The String?.orPlaceholder() extension is callable on a null value because its receiver type is nullable — handy for clean null handling.
Your turn. Replace the TODO , then run and compare.
Write one extension function and one extension property on String .
📋 Quick Reference — Extensions
Practice quiz
What does an extension function let you do?
- Add a function to an existing type without editing or subclassing it
- Rewrite the original class source
- Make a class final
- Remove methods from a type
Answer: Add a function to an existing type without editing or subclassing it. Extensions add methods to existing types without modifying or subclassing them.
Inside an extension function, what does 'this' refer to?
- The enclosing file
- The receiver — the value it was called on
- Always null
- The companion object
Answer: The receiver — the value it was called on. this refers to the receiver, the value the extension is called on.
How are extension functions dispatched?
- Dynamically at runtime
- By reflection only
- Statically, based on the declared type of the receiver
- Randomly
Answer: Statically, based on the declared type of the receiver. Extensions resolve statically using the declared (compile-time) type of the receiver.
Why can't an extension property have a backing field?
- Because they are always val
- Because the extension is not part of the original class, so there is nowhere to store state
- Because Kotlin forbids properties entirely
- Because they must be private
Answer: Because the extension is not part of the original class, so there is nowhere to store state. An extension isn't part of the class, so it has no place to store state; it must be computed.
If a member function and an extension have the same name, which is called?
- The extension always
- The member function wins
- Whichever is imported last
- It is a compile error
Answer: The member function wins. Members win over extensions when both have the same signature.
How can an extension be called safely on a possibly-null value?
- It cannot ever be called on null
- By declaring the receiver type as nullable (Type?)
- By marking it private
- By making it a member
Answer: By declaring the receiver type as nullable (Type?). An extension on a nullable receiver (Type?) can handle null itself.
How does the compiler implement myString.shout()?
- As a static call passing the string as a hidden receiver argument
- By editing the String class
- By creating a subclass of String
- By boxing into an Object
Answer: As a static call passing the string as a hidden receiver argument. The call compiles to a static call with the receiver passed as a hidden first argument.
Can extension functions take parameters?
- No, never
- Only one parameter
- Only parameters of the receiver type
- Yes, like any function
Answer: Yes, like any function. Extensions can take parameters just like ordinary functions.
What must happen for an extension to be usable elsewhere?
- It must be imported (or in the same file/package)
- It must be public and abstract
- It must be inside a data class
- Nothing; all extensions are global
Answer: It must be imported (or in the same file/package). Extensions must be imported or be in the same file/package to be visible.
When should you prefer a member function over an extension?
- Never; extensions are always better
- When you need true runtime polymorphism via overriding
- When the receiver is a String
- When you want IDE autocomplete
Answer: When you need true runtime polymorphism via overriding. For polymorphic behaviour chosen at runtime, use an open member function and override it.