En este artículo, aprenderá sobre interfaces y cómo implementarlas en Kotlin con la ayuda de ejemplos.
Las interfaces de Kotlin son similares a las interfaces en Java 8. Pueden contener definiciones de métodos abstractos así como implementaciones de métodos no abstractos. Sin embargo, no pueden contener ningún estado.
Es decir, la interfaz puede tener propiedades, pero debe ser abstracta o debe proporcionar implementaciones de acceso.
Lectura recomendada: Clase abstracta de Kotlin
Las clases abstractas en Kotlin son similares a la interfaz con una diferencia importante. No es obligatorio que las propiedades de una clase abstracta sean abstractas o proporcionen implementaciones de acceso.
¿Cómo definir una interfaz?
La palabra clave interface
se utiliza para definir interfaces en Kotlin. Por ejemplo,
interface MyInterface (var test: String // propiedad abstracta fun foo () // método abstracto fun hello () = "Hola" // método con implementación predeterminada)
Aquí,
- Se crea una interfaz MyInterface.
- la interfaz tiene una prueba de propiedad abstracta y un método abstracto
foo()
. - la interfaz también tiene un método no abstracto
hello()
.
¿Cómo implementar la interfaz?
Así es como una clase u objeto puede implementar la interfaz:
interfaz MyInterface (val test: Int // propiedad abstracta fun foo (): String // método abstracto (devuelve String) fun hello () (// método con implementación predeterminada // cuerpo (opcional))) clase InterfaceImp: MyInterface (anular val test: Int = 25 anular fun foo () = "Lol" // otro código)
Aquí, una clase InterfaceImp implementa la interfaz MyInterface.
La clase anula los miembros abstractos (propiedad y foo()
método de prueba ) de la interfaz.
Ejemplo: ¿Cómo funciona la interfaz?
interface MyInterface ( val test: Int fun foo() : String fun hello() ( println("Hello there, pal!") ) ) class InterfaceImp : MyInterface ( override val test: Int = 25 override fun foo() = "Lol" ) fun main(args: Array) ( val obj = InterfaceImp() println("test = $(obj.test)") print("Calling hello(): ") obj.hello() print("Calling and printing foo(): ") println(obj.foo()) )
Cuando ejecute el programa, la salida será:
test = 25 Llamando hello (): ¡Hola, amigo! Llamar e imprimir foo (): Lol
Como se mencionó anteriormente, una interfaz también puede tener una propiedad que proporcione implementación de acceso. Por ejemplo,
interface MyInterface ( // property with implementation val prop: Int get() = 23 ) class InterfaceImp : MyInterface ( // class body ) fun main(args: Array) ( val obj = InterfaceImp() println(obj.prop) )
Cuando ejecute el programa, la salida será:
23
Aquí, prop no es abstracto. Sin embargo, es válido dentro de la interfaz porque proporciona implementación para el descriptor de acceso.
Sin embargo, no puede hacer algo como val prop: Int = 23
dentro de la interfaz.
Implementar dos o más interfaces en una clase
Kotlin no permite una verdadera herencia múltiple. Sin embargo, es posible implementar dos o más interfaces en una sola clase. Por ejemplo,
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMeToo() ( println("From interface B") ) ) // implements two interfaces A and B class Child: A, B fun main(args: Array) ( val obj = Child() obj.callMe() obj.callMeToo() )
Cuando ejecute el programa, la salida será:
Desde la interfaz A Desde la interfaz B
Resolución de conflictos primordiales (interfaz múltiple)
Supongamos que dos interfaces (A y B) tienen un método no abstracto con el mismo nombre (digamos callMe()
método). Implementaste estas dos interfaces en una clase (digamos C). Ahora, si llama al callMe()
método usando el objeto de la clase C, el compilador arrojará un error. Por ejemplo,
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMe() ( println("From interface B") ) ) class Child: A, B fun main(args: Array) ( val obj = Child() obj.callMe() )
Aquí está el error:
Error: (14, 1) Kotlin: La clase 'C' debe anular la diversión pública abierta callMe (): Unidad definida en A porque hereda múltiples métodos de interfaz de la misma
Para resolver este problema, debe proporcionar su propia implementación. Así es cómo:
interface A ( fun callMe() ( println("From interface A") ) ) interface B ( fun callMe() ( println("From interface B") ) ) class C: A, B ( override fun callMe() ( super.callMe() super.callMe() ) ) fun main(args: Array) ( val obj = C() obj.callMe() )
Ahora, cuando ejecute el programa, la salida será:
Desde la interfaz A Desde la interfaz B
Aquí, la implementación explícita del callMe()
método se proporciona en la clase C.
clase C: A, B (anula la diversión callMe () (super.callMe () super .callMe ()))
La declaración super.callMe()
llama al callMe()
método de clase A. De manera similar, llama al método de clase .super.callMe()
callMe()
B