Sobes.tech
Middle

Wat is het verschil tussen sealed-klassen en abstracte klassen in Kotlin?

sobes.tech AI

Antwoord van AI

Het belangrijkste verschil tussen sealed-klassen en abstracte klassen is dat sealed-klassen de erfhiërarchie beperken tot één bestand of module (voor Kotlin 1.5+). De afgeleiden van een sealed-klasse moeten in hetzelfde bestand als de sealed-klasse zelf worden gedeclareerd, wat een volledige controle garandeert bij het gebruik van when-uitdrukkingen.

Verschillen:

  • Erfelijkheid:
    • Abstracte klassen kunnen overal in het project worden geërfd.
    • Sealed-klassen kunnen alleen binnen hetzelfde bestand (voor Kotlin 1.5) of binnen dezelfde module (met Kotlin 1.5+) worden geërfd.
  • Gebruik met when:
    • Bij gebruik van when met een sealed-type kan de compiler controleren of alle mogelijke subtypen zijn overwogen, waardoor when volledig wordt en het expliciet aangeven van een else-tak niet nodig is als alle subtypen worden afgehandeld.
    • Bij abstracte klassen kan de compiler de volledigheid niet garanderen, dus is een else vaak nodig.
  • Aanmaken van instanties:
    • Noch sealed- noch abstracte klassen kunnen direct worden geïnstantieerd.
  • Leden:
    • Zowel abstracte als sealed-klassen kunnen abstracte en niet-abstracte leden hebben.

Voorbeeld van een sealed-klasse:

sealed class Result<out T> {
    data class Success<out T>(val data: T) : Result<T>()
    data class Error(val message: String) : Result<Nothing>()
}

fun processResult(result: Result<Int>) {
    when (result) {
        is Result.Success -> {
            // Verwerking van succesvol resultaat
            println("Succes: ${result.data}")
        }
        is Result.Error -> {
            // Verwerking van fout
            println("Fout: ${result.message}")
        }
        // Geen else nodig als alle afgeleiden worden afgehandeld
    }
}

Voorbeeld van een abstracte klasse:

abstract class Shape {
    abstract fun area(): Double
}

class Circle(val radius: Double) : Shape() {
    override fun area(): Double = Math.PI * radius * radius
}

class Rectangle(val width: Double, val height: Double) : Shape() {
    override fun area(): Double = width * height
}

fun calculateArea(shape: Shape): Double {
    return shape.area()
}

Wanneer gebruiken:

  • Sealed-klassen: Ideaal voor het weergeven van een beperkte set mogelijke toestanden of typen, wanneer volledige controle in when-uitdrukkingen nodig is. Vaak gebruikt voor het modelleren van operationele resultaten (succes/fout), UI-toestanden, gebeurtenissen.
  • Abstracte klassen: Geschikt voor het definiëren van algemene functionaliteit en contracten voor een groep gerelateerde klassen die overal in het project kunnen worden geërfd.

Kortom, sealed-klassen bieden strengere controle over de erfhiërarchie en verbeteren de veiligheid en leesbaarheid van de code bij het omgaan met een beperkte set subtypen.