What if you could add new powers to any class without touching its original code?
Why Extension function syntax in Kotlin? - Purpose & Use Cases
Imagine you want to add a new action to a class you didn't create, like adding a new button to a remote control that only has a few buttons.
Without extension functions, you'd have to create a new class that copies all the original features plus your new one, which is slow and error-prone. Or you'd clutter your code with helper functions that don't feel like they belong.
Extension functions let you add new actions directly to existing classes without changing them. It's like magically adding a new button to the remote that works just like the original ones.
fun printHello(name: String) { println("Hello, $name") }fun String.printHello() { println("Hello, $this") }You can cleanly add new behaviors to existing classes, making your code easier to read and maintain.
Adding a function to the String class to check if it's a valid email, without changing the original String class.
Extension functions add new features to existing classes without modifying them.
They keep your code clean and easy to understand.
They save time and reduce errors compared to manual workarounds.
Practice
greet for the String type in Kotlin?Solution
Step 1: Understand extension function syntax
Extension functions use the syntaxfun ReceiverType.functionName(). Here,Stringis the receiver type.Step 2: Match the syntax with options
fun String.greet() { println("Hello, $this") } correctly usesfun String.greet(). Other options do not follow this syntax.Final Answer:
fun String.greet() { println("Hello, $this") } -> Option CQuick Check:
Extension function syntax = fun ReceiverType.functionName() [OK]
- Using 'extension' keyword which doesn't exist
- Placing receiver type as function parameter
- Missing receiver type before function name
square for Int that returns the square of the number?Solution
Step 1: Check extension function declaration with return type
The syntax isfun ReceiverType.functionName(): ReturnType = expression. fun Int.square(): Int = this * this matches this.Step 2: Verify usage of 'this' and return
fun Int.square(): Int = this * this correctly usesthis * thisand returns Int. fun Int.square() { this * this } uses braces (block body) but misses return statement, thus returns Unit. fun Int.square() = Int * Int uses invalidInt * Int.Final Answer:
fun Int.square(): Int = this * this -> Option AQuick Check:
Extension function with return type = fun ReceiverType.functionName(): Type [OK]
- Placing receiver type as function parameter
- Using braces without return in expression body
- Incorrect return type placement
fun String.shout() = this.uppercase() + "!"
fun main() {
val word = "hello"
println(word.shout())
}Solution
Step 1: Understand the extension function behavior
The extension functionshoutconverts the string to uppercase and adds an exclamation mark.Step 2: Apply the function to the string "hello"
Callingword.shout()returns "HELLO!" which is printed.Final Answer:
HELLO! -> Option BQuick Check:
Extension function output = uppercase + "!" [OK]
- Assuming original string changes
- Ignoring uppercase conversion
- Thinking extension functions modify original object
fun Int.double {
return this * 2
}Solution
Step 1: Check function declaration syntax
Functions must have parentheses after the name, even if no parameters are present. Here,doublemisses parentheses.Step 2: Verify other parts
Usingthisis valid in extension functions. Return statements are allowed. Extension functions can be declared for Int.Final Answer:
Missing parentheses after function name -> Option AQuick Check:
Function declaration requires parentheses () [OK]
- Omitting parentheses in function declaration
- Misunderstanding 'this' usage
- Thinking return is disallowed
isEven() to Int? (nullable Int) that returns true if the number is even, and false if it's odd or null. Which is the correct way to declare this extension function?Solution
Step 1: Understand nullable receiver type
To extend nullable Int, useInt?as receiver type. fun Int?.isEven(): Boolean = this != null && this % 2 == 0 does this correctly.Step 2: Check logic for null and even check
fun Int?.isEven(): Boolean = this != null && this % 2 == 0 uses concise expression: returns false if null, true if even. fun Int?.isEven(): Boolean { if (this == null) return false else return this % 2 != 0 } is verbose but has incorrect logic (returns true for odd). fun Int.isEven(): Boolean = this % 2 == 0 || this == null incorrectly uses non-nullable receiver and wrong logic. fun Int.isEven(): Boolean = this % 2 == 0 ignores null.Final Answer:
fun Int?.isEven(): Boolean = this != null && this % 2 == 0 -> Option DQuick Check:
Nullable receiver uses '?' and checks null explicitly [OK]
- Not using nullable receiver type for Int?
- Ignoring null checks inside function
- Using non-nullable receiver for nullable types
Ready to prove it?
Pass the test and this pattern moves unknown
