Sling Academy
Home/Kotlin/Practical Use Cases for Sealed Classes in Kotlin

Practical Use Cases for Sealed Classes in Kotlin

Last updated: November 30, 2024

In Kotlin, sealed classes are beneficial when you have a fixed set of types that a value can belong to, and you want to enforce this constraint at compile time. Sealed classes improve safety and clarity by ensuring your program handles every possible subclass within a defined hierarchy. Let's explore some practical use cases of sealed classes in Kotlin, accompanied by code examples.

What are Sealed Classes?

A sealed class is an abstract class that can only be subclassed within the same package. The Kotlin compiler knows all the subclasses at compile-time, which makes it easier to handle all instances of the sealed class appropriately. In this way, sealed classes allow you to define restricted class hierarchies that provide more guarantees than regular inheritance.

sealed class Operation {
    class Add(val value: Int) : Operation()
    class Subtract(val value: Int) : Operation()
    class Multiply(val value: Int) : Operation()
    class Divide(val value: Int) : Operation()
}

In this example, Operation is a sealed class which allows for an explicitly restricted set of actions a calculator can perform. You cannot add a new operation elsewhere in the code base without modifying the original sealed class declaration.

Sealed Classes for Handling UI State

Sealed classes are particularly useful when representing UI states, such as loading, success, or error states. This pattern is common when dealing with network requests.

sealed class UiState {
    object Loading : UiState()
    data class Success<T>(val data: T) : UiState()
    data class Error(val exception: Throwable) : UiState()
}

In this example, we have a sealed class UiState that represents three states: Loading, Success, and Error. The object Loading represents a loading state, whereas Success wraps the successful data response, and Error wraps an exception that may have occurred.

Sealed Classes in Expression Evaluation

Another real-world application of sealed classes is in representing expressions in a type-safe manner. By defining the different types of expressions as subclasses of a sealed class, evaluation and transformation become more robust and error-proof.

sealed class Expr {
    data class Const(val number: Double) : Expr()
    data class Sum(val left: Expr, val right: Expr) : Expr()
    data class Mult(val left: Expr, val right: Expr) : Expr()
}

fun eval(expr: Expr): Double = when (expr) {
    is Expr.Const -> expr.number
    is Expr.Sum -> eval(expr.left) + eval(expr.right)
    is Expr.Mult -> eval(expr.left) * eval(expr.right)
}

In this example, an expression can be a constant, a sum, or a multiplication. The sealed class Expr ensures that any additional types of expressions must be explicitly handled within the eval function, providing enhanced compile-time checks.

By utilizing sealed classes like this, your codebase benefits from improved type safety and readability, as programmers can quickly understand every subclass being used under a particular sealed class, without having to guess about unlisted implementations.

Next Article: Understanding Encapsulation in Object-Oriented Programming in Kotlin

Previous Article: Using Sealed Classes for Restricted Class Hierarchies in Kotlin

Series: Kotlin Object-Oriented Programming

Kotlin

You May Also Like

  • How to Use Modulo for Cyclic Arithmetic in Kotlin
  • Kotlin: Infinite Loop Detected in Code
  • Fixing Kotlin Error: Index Out of Bounds in List Access
  • Setting Up JDBC in a Kotlin Application
  • Creating a File Explorer App with Kotlin
  • How to Work with APIs in Kotlin
  • What is the `when` Expression in Kotlin?
  • Writing a Script to Rename Multiple Files Programmatically in Kotlin
  • Using Safe Calls (`?.`) to Avoid NullPointerExceptions in Kotlin
  • Chaining Safe Calls for Complex Operations in Kotlin
  • Using the Elvis Operator for Default Values in Kotlin
  • Combining Safe Calls and the Elvis Operator in Kotlin
  • When to Avoid the Null Assertion Operator (`!!`) in Kotlin
  • How to Check for Null Values with `if` Statements in Kotlin
  • Using `let` with Nullable Variables for Scoped Operations in Kotlin
  • Kotlin: How to Handle Nulls in Function Parameters
  • Returning Nullable Values from Functions in Kotlin
  • Safely Accessing Properties of Nullable Objects in Kotlin
  • How to Use `is` for Nullable Type Checking in Kotlin