In de vroege versies van Kotlin werden sealed classes gebruikt om de typehiërarchie te beperken, waardoor ontwikkelaars de toegestane subtypes expliciet konden beheersen door alleen kindklassen binnen één bestand te declareren. Voor sommige taken was dit niet voldoende, vooral als het nodig was om soortgelijke hiërarchieën met interfaces te beschrijven. Om dit probleem op te lossen, werd met Kotlin 1.5 de sealed modifier voor interfaces geïntroduceerd.
Gewone interfaces kunnen overal in het project worden geïmplementeerd, wat vaak het waarborgen van de absolute sluiting van de typehiërarchie en het gebruik van uitputtende typecontroles (exhaustive when) in de weg staat. Dit kan leiden tot runtime-fouten en het onvermogen om alle varianten statisch te controleren.
Sealed interfaces maken het mogelijk om de lijst van implementerende klassen binnen één bestand te beperken, waardoor de voorspelbaarheid van het type-systeem en de veiligheid van patroonmatching worden verhoogd.
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}") // Alle varianten zijn overwogen, 'else' is niet nodig }
Belangrijke kenmerken:
Kan een sealed interface in een apart bestand worden toegevoegd of buiten het oorspronkelijke bestand worden geïmplementeerd?
Nee. Alle types die direct een sealed interface implementeren, moeten in hetzelfde bestand zijn gedeclareerd; anders geeft de compiler een foutmelding.
Mag een sealed interface subinterfaces buiten het declaratiebestand hebben?
Nee. Subinterfaces moeten ook in hetzelfde bestand staan. De hele hiërarchie is binnen het bestand gesloten.
Beïnvloeden sealed interfaces de runtime-prestaties?
Niet direct, maar ze maken veilige typecontroles tijdens de compilatie mogelijk, wat de kans op runtime-fouten verkleint, de code vereenvoudigt en indirect de tests kan versnellen.
Een ontwikkelaar declareert een sealed interface NetworkAction in één bestand, maar de implementaties zijn verspreid over verschillende klassen en bestanden. Het probleem wordt later ontdekt: de compiler geeft aan dat de regel is geschonden, en het is moeilijk om de structuur te corrigeren, vooral in een groot project.
Voordelen:
Nadelen:
De sealed interface OrderResult en de klassen Success/Failure worden binnen één bestand gedeclareerd. De when-controle is altijd uitputtend, geen enkele tak is overgeslagen.
Voordelen:
Nadelen: