Easy Tutorial
❮ Kotlin Condition Control Otlin Android Setup ❯

Kotlin Extensions

Kotlin allows for the extension of properties and methods of a class without the need for inheritance or the use of the Decorator pattern.

Extensions are a static behavior and do not affect the code of the class being extended in any way.


Extension Functions

Extension functions can add new methods to an existing class without modifying the original class. The definition format for an extension function is:

fun receiverType.functionName(params){
    body
}

The following example extends the User class:

class User(var name:String)

/**Extension function**/
fun User.Print(){
    print("Username $name")
}

fun main(arg:Array<String>){
    var user = User("tutorialpro")
    user.Print()
}

The output of the example execution is:

Username tutorialpro

The following code is for MutableList:

// Extension function swap, swaps values at different positions
fun MutableList<Int>.swap(index1: Int, index2: Int) {
    val tmp = this[index1]     // 'this' corresponds to this list
    this[index1] = this[index2]
    this[index2] = tmp
}

fun main(args: Array<String>) {

    val l = mutableListOf(1, 2, 3)
    // The values at positions 0 and 2 are swapped
    l.swap(0, 2) // 'swap()' function's 'this' will point to the value of 'l'

    println(l.toString())
}

The output of the example execution is:

[3, 2, 1]

The 'this' keyword refers to the receiver object (that is, the object instance specified before the dot when calling the extension function).


Extension Functions are Static Dispatch

Extension functions are statically dispatched and are not virtual members of the receiver type. When calling an extension function, which function is specifically called is determined by the object expression of the calling function, not by the dynamic type:

open class C

class D: C()

fun C.foo() = "c"   // Extension function foo

fun D.foo() = "d"   // Extension function foo

fun printFoo(c: C) {
    println(c.foo())  // Type is class C
}

fun main(arg:Array<String>){
    printFoo(D())
}

The output of the example execution is:

c

If an extension function and a member function are the same, the member function will be used first.

class C {
    fun foo() { println("Member function") }
}

fun C.foo() { println("Extension function") }

fun main(arg:Array<String>){
    var c = C()
    c.foo()
}

The output of the example execution is:

Member function

Extending a Null Object

Inside an extension function, you can use 'this' to determine whether the receiver is NULL. This allows you to call an extension function even if the receiver is NULL. For example:

fun Any?.toString(): String {
    if (this == null) return "null"
    // After null checking, "this" will automatically convert to a non-null type, so the following toString()
    // is resolved as a member function of the Any class
    return toString()
}
fun main(arg:Array<String>){
    var t = null
    println(t.toString())
}

The output of the example execution is:

null

In addition to functions, Kotlin also supports extending properties with properties:

val <T> List<T>.lastIndex: Int
    get() = size - 1

Extension properties can be defined in a class or a Kotlin file, but not within a function. Initializer properties are not allowed because properties do not have a backend field (backing field), and can only be defined by explicitly provided getter/setter.

val Foo.bar = 1 // Error: Extension properties cannot have initializers

Extension properties can only be declared as val.


Extension of Companion Object

If a class defines a companion object, you can also define extension functions and properties for the companion object.

The companion object is called in the form of "ClassName.", and the extension functions declared by the companion object are called using the class name as a qualifier:

``` class MyClass { companion object { } // Will be called "Companion" }

fun MyClass.Companion.foo() { println("Extension function of companion object") }

val MyClass.Companion.no: Int get() = 10

fun main(args: Array<String>) { println("no:${My

❮ Kotlin Condition Control Otlin Android Setup ❯