Sobes.tech
Middle

Aký je rozdiel medzi sealed triedami a abstraktnými triedami v Kotlin?

sobes.tech AI

Odpoveď od AI

Hlavný rozdiel medzi sealed triedami a abstraktnými triedami spočíva v tom, že sealed triedy obmedzujú hierarchiu dedičnosti na úroveň jedného súboru alebo modulu (pre Kotlin 1.5+). Dediči sealed triedy musia byť deklarovaní v rovnakom súbore ako samotná sealed trieda, čo zabezpečuje úplnú kontrolu pri použití výrazov when.

Rozdiely:

  • Dedičstvo:
    • Abstraktné triedy môžu byť dedené kdekoľvek v projekte.
    • Sealed triedy môžu byť dedené iba v rámci toho istého súboru (do Kotlin 1.5) alebo v rámci toho istého modulu (s Kotlin 1.5+).
  • Použitie s when:
    • Pri použití when so sealed typom môže kompilátor skontrolovať, či boli všetky možné podtypy zahrnuté, čo robí when úplným a odstraňuje potrebu explicitne uvádzať vetvu else, ak sú všetky podtypy spracované.
    • S abstraktnými triedami kompilátor nemôže garantovať úplnosť, preto je často potrebné else.
  • Vytváranie inštancií:
    • Ani abstraktné, ani sealed triedy nie je možné priamo inštancovať.
  • Členovia:
    • Rovnako ako abstraktné, tak aj sealed triedy môžu mať abstraktné a neabstraktné členy.

Príklad sealed triedy:

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 -> {
            // Spracovanie úspešného výsledku
            println("Success: ${result.data}")
        }
        is Result.Error -> {
            // Spracovanie chyby
            println("Error: ${result.message}")
        }
        // Nie je potrebné else, ak sú všetci dedičia spracovaní
    }
}

Príklad abstraktnej triedy:

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()
}

Kedy použiť:

  • Sealed triedy: Ideálne na reprezentáciu obmedzeného súboru možných stavov alebo typov, keď potrebujete úplnú kontrolu v when výrazoch. Často sa používajú na modelovanie výsledkov operácií (úspech/chyba), stavov UI, udalostí.
  • Abstraktné triedy: Vhodné na definovanie spoločnej funkčnosti a kontraktu pre skupinu súvisiacich tried, ktoré môžu byť dedené kdekoľvek v projekte.

Celkovo, sealed triedy poskytujú prísnejšiu kontrolu nad hierarchiou dedičnosti a zlepšujú bezpečnosť a čitateľnosť kódu pri spracovaní obmedzeného počtu podtypov.