Kotlin Tutoial
Basics
Control Flow
Array & String
Functions
Collections
OOPs Concept
Exception Handling
Null Safety
Regex & Ranges
Java Interoperability
Miscellaneous
Android
Sealed classes in Kotlin are used to represent restricted class hierarchies, wherein a value can have one of the types from a limited set. They're a way to ensure type-safety when evaluating cases for a specific type. Sealed classes are often used in scenarios where you have a fixed set of related types, like when modeling states, events, or commands.
sealed
modifier.Consider modeling a UI state:
sealed class UiState { object Loading : UiState() data class Success(val data: String) : UiState() data class Error(val error: Throwable) : UiState() } fun handleUiState(state: UiState) { when (state) { is UiState.Loading -> println("Loading...") is UiState.Success -> println("Data: ${state.data}") is UiState.Error -> println("Error: ${state.error.message}") } }
when
expression. This means you won't miss any cases accidentally.Sealed classes can also have subclasses which are sealed:
sealed class Expr { data class Const(val number: Double) : Expr() data class Sum(val e1: Expr, val e2: Expr) : Expr() sealed class Function : Expr() { data class Sin(val angle: Expr) : Function() data class Cos(val angle: Expr) : Function() } }
Starting from Kotlin 1.5, you can also have sealed interfaces:
sealed interface Operation { object Add : Operation object Subtract : Operation data class Multiply(val factor: Int) : Operation }
Sealed classes in Kotlin provide a way to represent a fixed set of related types. They enhance type-safety, enable more readable and maintainable code, and work great with when
expressions by ensuring exhaustiveness. They're commonly used in design patterns like the MVI (Model-View-Intent) pattern in Android to represent distinct states or intents.
Subclasses and inheritance in Kotlin sealed classes:
sealed class Result { data class Success(val data: String) : Result() data class Error(val message: String) : Result() }
When to use sealed classes in Kotlin:
fun processResult(result: Result) { when (result) { is Result.Success -> handleSuccess(result.data) is Result.Error -> handleError(result.message) } }
Pattern matching with sealed classes in Kotlin:
when (result) { is Result.Success -> handleSuccess(result.data) is Result.Error -> handleError(result.message) }
Sealed classes vs enums in Kotlin:
sealed class Result { data class Success(val data: String) : Result() data class Error(val message: String) : Result() }
Companion objects in Kotlin sealed classes:
sealed class Result { data class Success(val data: String) : Result() { companion object { fun createDefault() = Success("Default") } } data class Error(val message: String) : Result() }
Using sealed classes for state management in Kotlin:
sealed class ViewState { object Loading : ViewState() data class Success(val data: String) : ViewState() data class Error(val message: String) : ViewState() }
Sealed classes and exhaustive when expressions in Kotlin:
when
expressions for better code safety.when (result) { is Result.Success -> handleSuccess(result.data) is Result.Error -> handleError(result.message) }
Sealed classes and polymorphism in Kotlin:
fun processResult(result: Result) { // Polymorphic behavior result.handle() }
Sealed classes and data classes in Kotlin:
sealed class Result { data class Success(val data: String) : Result() data class Error(val message: String) : Result() }
Sealed classes in Kotlin and Java interoperability:
// Java code public class JavaClass { public void processResult(Result result) { // Handle Result } }