0
0
KotlinComparisonBeginner · 4 min read

Extension Function vs Member Function in Kotlin: Key Differences and Usage

In Kotlin, a member function is defined inside a class and has access to its private members, while an extension function is defined outside the class and adds functionality without modifying the original class. Extension functions cannot access private members but allow adding new behavior to existing classes easily.
⚖️

Quick Comparison

This table summarizes the main differences between member functions and extension functions in Kotlin.

AspectMember FunctionExtension Function
DefinitionFunction declared inside a classFunction declared outside a class with receiver type
Access to private membersYes, can access private and protected membersNo, cannot access private or protected members
Modification of original classModifies class by adding functionDoes not modify class, adds functionality externally
Dispatch mechanismVirtual dispatch (polymorphic)Static dispatch (resolved at compile time)
Use caseCore behavior of classAdd functionality to classes without inheritance or source change
Syntaxfun functionName() { } inside class bodyfun ClassName.functionName() { } outside class body
⚖️

Key Differences

Member functions are part of the class definition. They have full access to the class's internal state, including private and protected members. This means they can manipulate the class's data directly and participate in polymorphism through overriding.

Extension functions are declared outside the class using a special syntax that specifies the receiver type. They allow you to add new functions to existing classes without changing their source code or using inheritance. However, they cannot access private or protected members of the class because they are not actually part of the class.

Another important difference is how Kotlin resolves calls: member functions use virtual dispatch, meaning the actual function called depends on the runtime type of the object. Extension functions use static dispatch, so the function called depends on the compile-time type of the variable, which can lead to different behavior in inheritance scenarios.

⚖️

Code Comparison

Here is an example showing a member function inside a class that returns a greeting message.

kotlin
class Person(val name: String) {
    fun greet(): String {
        return "Hello, $name!"
    }
}

fun main() {
    val person = Person("Alice")
    println(person.greet())
}
Output
Hello, Alice!
↔️

Extension Function Equivalent

The same greeting functionality can be added as an extension function outside the Person class.

kotlin
class Person(val name: String)

fun Person.greet(): String {
    return "Hello, $name!"
}

fun main() {
    val person = Person("Alice")
    println(person.greet())
}
Output
Hello, Alice!
🎯

When to Use Which

Choose member functions when you control the class source and need to access or modify its internal state or want to use polymorphism. They are best for core behaviors tightly coupled with the class.

Choose extension functions when you want to add utility or helper functions to classes you do not own or cannot modify, or when you want to keep your code modular and clean without inheritance. They are ideal for adding functionality without changing existing code.

Key Takeaways

Member functions belong inside the class and can access all its members including private ones.
Extension functions add new behavior externally but cannot access private or protected members.
Member functions support polymorphism; extension functions are resolved statically at compile time.
Use member functions for core class behavior and extension functions for adding utilities or helpers.
Extension functions help keep code modular and extend classes without inheritance or source changes.