En Kotlin, la palabra clave super se utiliza para referirse a la implementación de un método o propiedad de la superclase o de la interfaz implementada. A diferencia de Java, Kotlin permite especificar explícitamente a través de qué interfaz o clase se debe invocar la implementación del método, lo que es especialmente importante en caso de "conflicto" entre múltiples interfaces con métodos idénticos.
Particularidad: Si una clase implementa múltiples interfaces en las que se define un método con la misma firma y hay una implementación predeterminada, es necesario especificar explícitamente qué implementación usar.
Ejemplo:
interface A { fun foo() = println("A") } interface B { fun foo() = println("B") } class C : A, B { override fun foo() { super<A>.foo() // Llamamos explícitamente a A.foo super<B>.foo() // Llamamos explícitamente a B.foo } }
Esto no se admite directamente en Java (Java no permite que las interfaces tengan campos/implementaciones de métodos hasta Java 8, e incluso en Java 8, los mecanismos son diferentes).
"¿Se puede en Kotlin referir a la implementación del método de la superclase a través de múltiples niveles de herencia?"
super<Intermediate>.foo(), pero no es así: solo se puede referir a la superclase inmediata o a la interfaz que implementa directamente dicho método.Ejemplo:
open class Base { open fun foo() = println("Base") } open class Mid : Base() { override fun foo() { println("Mid"); super.foo() } } class Child: Mid() { override fun foo() { super.foo() // llamará a Mid.foo() // super<Base>.foo() — error de compilación } }
Historia
En un gran proyecto, las interfaces
LoggeryAuditorambas definieron el métodorecord(). Al implementar la clase que hereda ambas interfaces, el programador no sobrescribió explícitamenterecord(), resultando en un error de compilación "La clase debe sobrescribir la función pública abierta record()". Tuvo que implementar el método manualmente y delegar explícitamente en la interfaz correspondiente.
Historia
Al intentar invocar el método implementado de la superclase a través de múltiples capas intermedias (por ejemplo,
super<Base>.foo()), se produjo un error de compilación. El desarrollador no conocía las limitaciones de Kotlin y no podía entender por qué la llamada directa no era posible.
Historia
Después de la actualización de la API, una de las interfaces añadió una implementación de función predeterminada que coincidía con otra interfaz. El código antiguo dejó de compilarse debido a un conflicto de implementaciones, y se tuvo que resolver el conflicto explícitamente implementando el método uno mismo y eligiendo qué implementaciones de las superinterfaces invocar internamente.