Función de extensión de Kotlin

Kotlin le da al programador la capacidad de agregar más funcionalidad a las clases existentes, sin heredarlas . Esto se logra a través de una característica conocida como extensiones . Cuando se agrega una función a una clase existente, se conoce como función de extensión . Para agregar una función de extensión a una clase, defina una nueva función adjunta al nombre de la clase como se muestra en el siguiente ejemplo: 

Kotlin

package kotlin1.com.programmingKotlin.chapter1
 
// A sample class to demonstrate extension functions
class Circle (val radius: Double){
    // member function of class
    fun area(): Double{
        return Math.PI * radius * radius;
    }
}
fun main(){
    // Extension function created for a class Circle
    fun Circle.perimeter(): Double{
        return 2*Math.PI*radius;
    }
    // create object for class Circle
    val newCircle = Circle(2.5);
    // invoke member function
    println("Area of the circle is ${newCircle.area()}")
    // invoke extension function
    println("Perimeter of the circle is ${newCircle.perimeter()}")
}

Producción: 

Area of the circle is 19.634954084936208
Perimeter of the circle is 15.707963267948966

Explicación: 

Aquí, se agrega una nueva función a la clase usando la notación de puntos con la clase Circle.perimeter() , y su tipo de devolución es Double. En la función principal, se crea un objeto para instanciar la clase Circle y se invoca la función en la instrucción println() . Cuando se invoca la función miembro, devuelve el área de un círculo y, de manera similar, la función de extensión devuelve el perímetro del círculo. 

Clase de biblioteca extendida usando la función de extensión

Kotlin no solo permite que se extiendan las clases definidas por el usuario, sino que también se pueden extender las clases de la biblioteca . La función de extensión se puede agregar a las clases de la biblioteca y usarse de manera similar a las clases definidas por el usuario. El siguiente ejemplo muestra una función de extensión creada para una clase de biblioteca: 

Kotlin

fun main(){
 
    // Extension function defined for Int type
    fun Int.abs() : Int{
        return if(this < 0) -this else this
    }
 
    println((-4).abs())
    println(4.abs())
}

Producción: 

4
4

Explicación: Aquí, hemos ampliado la función de biblioteca usando una función de extensión. Realizamos la operación de módulo en un valor entero. Hemos pasado el valor entero -4 y 4 y obtenido un valor positivo para ambos. Si el valor del parámetro es menor que 0, devuelve -(valor) y si el valor del parámetro es mayor que cero, devuelve el mismo valor. 

Las extensiones se resuelven estáticamente

Un punto importante a tener en cuenta sobre las funciones de extensión es que se resuelven estáticamente, es decir, qué función de extensión se ejecuta depende totalmente del tipo de expresión en la que se invoca, en lugar del tipo resuelto en la ejecución final de la expresión en tiempo de ejecución. . El siguiente ejemplo aclarará el argumento anterior:  

Kotlin

// Open class created to be inherited
open class A(val a:Int, val b:Int){
}
 
// Class B inherits A
class B():A(5, 5){}
 
fun main(){
     
    // Extension function operate defined for A
    fun A.operate():Int{
        return a+b
    }
 
    // Extension function operate defined for B
    fun B.operate():Int{
        return a*b;
    }
 
    // Function to display static dispatch
    fun display(a: A){
        print(a.operate())
    }
 
    // Calling display function
    display(B())
}

Producción: 

10

Explicación: 

Si está familiarizado con Java o cualquier otro lenguaje de programación orientado a objetos, puede notar en el programa anterior que, dado que la clase B hereda la clase A y el argumento pasado, la función de visualización es una instancia de la clase B. La salida debe ser 25 de acuerdo con el concepto del método dinámico dispatch , pero dado que las funciones de extensión se resuelven estáticamente, la función de operación se llama en el tipo A. Por lo tanto, la salida es 10. 

Receptor anulable

Las funciones de extensión también se pueden definir con el tipo de clase que acepta valores NULL . En este caso, cuando se agrega la verificación de nulo dentro de la función de extensión y se devuelve el valor apropiado.
Ejemplo de una función de extensión como receptor anulable:

Kotlin

// A sample class to display name name
class AB(val name: String){
    override fun toString(): String {
        return "Name is $name"
    }
}
 
fun main(){
    // An extension function as a nullable receiver
    fun AB?.output(){
        if(this == null){
            println("Null")
        }else{
            println(this.toString())
        }
    }
 
    val x = AB("Charchit")
     
    // Extension function called using an instance
    x.output()
    // Extension function called on null
    null.output()
}

Producción: 

Name is Charchit
Null

Extensiones de objetos complementarios

Si una clase contiene un objeto complementario, también podemos definir funciones y propiedades de extensión para el objeto complementario. Declaración de objeto complementario –  

Kotlin

class MyClass {
    // companion object declaration
    companion object {
        fun display(){
            println("Function declared in companion object")
        }
    }
}
fun main(args: Array<String>) {
   // invoking member function
   val ob = MyClass.display() 
}

Producción: 

Function declared in companion object

Al igual que la llamada de la función miembro regular del objeto complementario, la función de extensión se puede llamar usando solo el nombre de la clase como calificador. Ejemplo de extensión de objeto complementario: 

Kotlin

class MyClass {
    companion object {
        // member function of companion object
        fun display(str :String) : String{
            return str
        }
    }
}
    // extension function of companion object
fun MyClass.Companion.abc(){
    println("Extension function of companion object")
}
fun main(args: Array<String>) {
    val ob = MyClass.display("Function declared in companion object")
    println(ob)
    // invoking the extension function
    val ob2 = MyClass.abc()
}

Producción: 

Function declared in companion object
Extension function of companion object

Publicación traducida automáticamente

Artículo escrito por CharchitKapoor y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *