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