Las interfaces en Kotlin te van a permitir una mayor reutilización de código de la que conseguías con Java.

La razón es muy sencilla: puedes añadir código a tus interfaces. Si has probado Java 8, es algo muy parecido.

Lo bueno de de poder incluir código en una interfaz es que podrás utilizar composición de forma mucho más potente. Ahora lo veremos.

Si quieres aprender cuál es la situación de Kotlin en el mercado, por qué debes aprenderlo y los primeros pasos para que veas lo fácil que es, he preparado un training gratuito de hora y media al que puedes unirte haciendo click aquí.

Las interfaces en Java 6

El problema con las interfaces de Java es que sólo podemos describir comportamiento, pero no implementarlo.

Esto es suficiente en muchos casos. Pero hay situaciones que no nos permite solucionar, pues nos obliga a delegar la implementación de dicha interfaz en objetos individuales si queremos conseguir una buena composición.

Todo esto hace que algo tan sencillo como poder componer el código de una clase mediante piezas reutilizables se vuelva bastante complicado.

Las interfaces en Kotlin

Kotlin nos trae una muy buena noticia: las interfaces pueden tener código.

Esto significa que podemos implementar un especie de herencia múltiple (algo limitada, en cualquier caso). Podemos hacer que una clase implemente varias interfaces, y que herede el comportamiento de cada una de ellas.

Implementar una interfaz con código es muy sencillo:

interface Interface1 {
    fun function1() {
        Log.d("Interface1", "function1 called")
    }
}

Podríamos tener otra interfaz 2 con otra función:

interface Interface2 {
    fun function2() {
        Log.d("Interface2", "function2 called")
    }
}

Y una clase que las implemente podría utilizar ambas sin problema:

class MyClass : Interface1, Interface2 {
    fun myFunction() {
        function1()
        function2()
    }
}

¡Genial! Esto nos da mucha mayor versatilidad a la hora de organizar nuestro código.

Las interfaces no pueden tener estado

Es una limitación importante a tener en cuenta. Podemos tener código pero no estado.

Esto quiere decir que no podemos crear una property y almacenar estado en ella. Si definimos una property en una interfaz, la clase que la implemente necesita sobrescribirla.

Vamos a ver un ejemplo. Imaginemos que la interfaz necesita un contexto:

interface Toaster {
    val context: Context

    fun toast(message: String) {
        Toast.makeText(context, message, Toast.LENGTH_SHORT).show()
    }
}

El código es sencillo. Es una interfaz que implementa un método que muestra un Toast. Para eso necesita el contexto.

Si tenemos una actividad que queremos que utilice esta interfaz, necesitaremos sobrescribir el contexto:

class MyActivity : AppCompatActivity(), Toaster {
    override val context = this

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        toast("onCreate")
    }
}

Así de sencillo. Asignamos la propia Activity como contexto, que la interfaz podrá utilizar para su función.

Ahora ya puedes usar las funciones de Toaster en la Activity sin ningún problema.

Delegación de interfaces

Otra funcionalidad muy interesante en Kotlin es la delegación de interfaces. Es una herramienta muy potente para conseguir una composición más limpia.

Imagina que tienes una clase C, compuesta por dos objetos de tipo A y B:

interface A {
    fun functionA(){}
}

interface B {
    fun functionB(){}
}

class C(val a: A, val b: B) {
    fun functionC(){
        a.functionA()
        b.functionB()
    }
}

La clase C utiliza las funciones A y B dentro de su propio código.

Si un objeto está compuesto por dos componentes, estaría muy bien que pudiera usar sus funciones directamente.

Hay otra forma de escribir este código y conseguir el mismo resultado, usando la delegación de interfaces:

class C(a: A, b: B): A by a, B by b {
    fun functionC(){
        functionA()
        functionB()
    }
}

Puedes ver que la clase C está implementando A y B, pero realmente está delegando la implementación en los objetos que recibe como parámetro.

De esta forma, puede usar las funciones de las interfaces como si fueran suyas.

Conclusión

Hemos visto las diferencias entre las clases de Java y las de Kotlin. Ahora trata de buscar en qué situaciones pueden simplificarte la vida, pues estas nuevas ideas te abren un mundo de posibilidades.

Tu código será más reutilizable que antes y mucho más legible.

Si todo esto te apasiona tanto como a mí, te animo a que te apuntes a mi training gratuito donde te contaré todo lo que necesitas para aprende a crear tus Apps Android en Kotlin desde cero

Author: Antonio Leiva

Soy un apasionado de Kotlin. Hace ya más de dos años que estudio el lenguaje y su aplicación a Android para ayudarte a ti a aprenderlo de la forma más sencilla posible.