Interfaces en Kotlin

Resultado de imagen de molde

class Interfaces {

    private var anonymousObjectImplementingInterface: Any? = null


    private fun showCase1(){
        anonymousObjectImplementingInterface = object:Interface1 {
            override fun abstractMethod() {
                //Poner codigo es totalmente opcional
            }
        }
        //Necesitamos castear ya que en la declaracion lo hacemos como Any y no puede inferir el tipo correctamente
        (anonymousObjectImplementingInterface as Interface1).methodWithImplementationByDefault()
        (anonymousObjectImplementingInterface as Interface1).abstractMethod()


    }

    private fun showCase2(){
        val aoii = object :Interface2{
            override val propertyAbstract: Int
                get() = 10
        }

        aoii.propertyAbstract
        aoii.propertyWithImplementation
        aoii.hello()
    }

    fun showCases(){
        showCase1()
        showCase2()
    }
}

interface Interface1{

    fun abstractMethod()

    fun methodWithImplementationByDefault(){

    }
}

interface Interface2{
    val propertyAbstract: Int
    var propertyWithImplementation: String
        get() = "ByDefault"
        set(value) {this.propertyWithImplementation = value}

    fun hello(){
        Log.w("INTERFACE-2","Is it working $propertyWithImplementation?, YaY! $propertyAbstract :)")
    }
}

Método Abstracto

Kotlin si en la declaración de un método no lo implementamos (no abrimos las llaves) nos lo marca como abstracto directamente.

Ejemplo –> fun abstractMethod()  sería igual a poner  abstract fun abstractMethod()

Propiedad Abstracta

Si no se le asigna ningún valor, Kotlin la marca como abstracta y al implementar la interface, obligara a darle un valor.

Ejemplo –> val propertyAbstract: Int

Inferencia de Tipos

Creamos una propiedad de tipo de tipo Any? (puede ser cualquier tipo) y lo inicializamos a null.

private var anonymousObjectImplementingInterface: Any? = null

o igualmente se podría hacer con lateinit

private lateinit var anonymousObjectImplementingInterface: Any

Aqui se podria lanzar un nullPointerException, pero Kotlin nos deja bajo nuestra responsabilidad.

showCase1

Creamos un objecto anónimo que implemente esa inferface.

Asignamos a ese objecto la interface

No se puede crear una instancia de una interface. En programación, las interface no tienen instancias. Lo que si se puede hacer es crear un objecto anónimo que implemente esa interface.

Al crear el objecto implementando la interface, nos obliga a implementar el método abstracto abstractMethod(), aunque la implementación esté vacía.

        anonymousObjectImplementingInterface = object:Interface1 {
            override fun abstractMethod() {
                //Poner código es totalmente opcional
            }
        }

El objectoanonymousObjectImplementingInterface al haberlo marcado como Any, aun haciendo la implementacion previa de la Interface1, debemos hacerle un casting para implementar todos los métodos cuando lo llamemos.

Dicho de otra forma, necesitamos castear ya que en la declaración lo hacemos como Any y no puede inferir el tipo correctamente.

(anonymousObjectImplementingInterface as Interface1).methodWithImplementationByDefault()
(anonymousObjectImplementingInterface as Interface1).abstractMethod()

showCase2

Creamos un objecto anónimo que implemente la interface2, obligándonos a implementar el método abstracto get().

val aoii = object :Interface2{
  override val propertyAbstract: Int
  get() = 10
}

En este caso, dejamos a Kotlin que infiera el tipo al val aoii, quitándonos el «problema» anterior de castear y demás, ya que no declaramos la variable como en el caso anterior como Any.