Sobes.tech
Middle

Czym są klasy 'sealed' w Kotlin i w jakich przypadkach należy ich używać?

sobes.tech AI

Odpowiedź od AI

Klasa sealed jest używana do reprezentowania ograniczonej hierarchii klas. Wszystkie bezpośrednie podtypy klasy sealed muszą być zdefiniowane w tym samym pliku co sama klasa sealed lub w tych samych modułach (dla Kotlin 1.5+). Pozwala to kompilatorowi sprawdzić, czy wszystkie możliwe podtypy są obsługiwane w wyrażeniu when, czyniąc je wyczerpującym bez konieczności dodawania gałęzi else.

Kluczowe cechy:

  • Wszystkie bezpośrednie podklasy muszą być lokalne.
  • Konstruktor klasy sealed jest domyślnie private.
  • Klasa sealed nie może być abstrakcyjna.
  • Nie pozwala na tworzenie instancji.

Przypadki użycia:

  • Reprezentacja ograniczonego zestawu stanów lub wyników. Na przykład Loading, Success(data), Error(message).
    sealed class Result<out T> {
       data class Success<T>(val data: T) : Result<T>()
       data class Error(val message: String) : Result<Nothing>()
       object Loading : Result<Nothing>()
    }
    
  • Obsługa wariantów w wyrażeniu when z gwarancją wyczerpania.
    fun processResult(result: Result<String>) {
       when (result) {
          is Result.Success -> println("Dane otrzymane: ${result.data}")
          is Result.Error -> println("Błąd: ${result.message}")
          Result.Loading -> println("Ładowanie...")
       }
       // Nie jest potrzebny gałąź `else`, ponieważ kompilator zna wszystkie podtypy.
    }
    
  • Użycie jako odpowiednik wyliczeń z możliwością enkapsulacji danych w każdej wariancie.

Porównanie z klasami enum:

Cecha enum class sealed class
Instancje Ograniczony zestaw nazwanych stałych Ograniczony zestaw typów
Dane w wariantach Nie (tylko właściwości) Tak (poprzez podklasy)
Członkowie abstrakcyjni Nie Tak
Dziedziczenie Nie Tak, ale ograniczone do tego samego pliku/modułu