En las primeras versiones de Kotlin, se utilizaban clases selladas para limitar la jerarquía de tipos, lo que permitía a los desarrolladores controlar explícitamente los subtipos permitidos limitando la declaración de herederos solo dentro de un archivo. Esto resultó insuficiente para algunas tareas, especialmente cuando se necesitaba describir jerarquías similares utilizando interfaces. Para resolver este problema, a partir de Kotlin 1.5, se introdujo el modificador sellado para las interfaces.
Las interfaces normales permiten su implementación en cualquier parte del proyecto, lo que a menudo dificulta garantizar el cierre absoluto de la jerarquía de tipos y utilizar comprobaciones exhaustivas de tipos (exhaustive when). Esto puede llevar a errores en tiempo de ejecución y a la imposibilidad de verificar estáticamente todas las variantes.
Las interfaces selladas permiten limitar la lista de clases de implementación dentro de un solo archivo, aumentando la previsibilidad del sistema de tipos y la seguridad en la coincidencia de patrones (pattern matching).
sealed interface NetworkResult class Success(val data: String): NetworkResult class Failure(val error: Throwable): NetworkResult fun handle(result: NetworkResult) = when(result) { is Success -> println("Data: ${result.data}") is Failure -> println("Error: ${result.error}") // Todos los casos están cubiertos, 'else' no es necesario }
Características clave:
¿Se puede añadir una sealed interface en un archivo separado o implementarla fuera del archivo original?
No. Todos los tipos que implementan directamente una sealed interface deben ser declarados en el mismo archivo; de lo contrario, el compilador mostrará un error.
¿Se permite que una sealed interface tenga subinterfaces fuera del archivo de declaración?
No. Las subinterfaces también deben encontrarse en el mismo archivo. Toda la jerarquía está cerrada dentro del archivo.
¿Afectan las sealed interfaces al rendimiento en tiempo de ejecución?
No directamente, pero permiten usar comprobaciones de tipos seguras en el momento de la compilación, lo que disminuye la probabilidad de errores en tiempo de ejecución, simplifica el código y puede acelerar indirectamente las pruebas.
Un desarrollador declara la sealed interface NetworkAction en un archivo, pero las implementaciones están dispersas en diferentes clases y archivos. Posteriormente se detecta el problema: el compilador indica una violación de la regla, y es complicado corregir la estructura, especialmente en un gran proyecto.
Pros:
Contras:
La sealed interface OrderResult y las clases Success/Failure se declaran dentro de un solo archivo. La verificación when es siempre exhaustiva, ningún caso queda desatendido.
Pros:
Contras: