Bird
Raised Fist0
Kotlinprogramming~20 mins

Sealed classes with when exhaustive check in Kotlin - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Sealed Class Mastery
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
Output of exhaustive when with sealed class
What is the output of this Kotlin code when shape is Shape.Circle(5.0)?
Kotlin
sealed class Shape {
    data class Circle(val radius: Double) : Shape()
    data class Rectangle(val width: Double, val height: Double) : Shape()
}

fun describe(shape: Shape): String {
    return when(shape) {
        is Shape.Circle -> "Circle with radius ${shape.radius}"
        is Shape.Rectangle -> "Rectangle with width ${shape.width} and height ${shape.height}"
    }
}

fun main() {
    val shape: Shape = Shape.Circle(5.0)
    println(describe(shape))
}
ACompilation error: when expression is not exhaustive
BRectangle with width 5.0 and height 5.0
CRuntime exception: Unhandled type
DCircle with radius 5.0
Attempts:
2 left
💡 Hint
Check how the when expression covers all subclasses of the sealed class.
❓ Predict Output
intermediate
2:00remaining
Exhaustive when with sealed interface and else branch
What will this Kotlin code print when status is Status.Loading?
Kotlin
sealed interface Status {
    object Loading : Status
    object Success : Status
    object Error : Status
}

fun statusMessage(status: Status): String {
    return when(status) {
        is Status.Success -> "Success!"
        is Status.Error -> "Error occurred."
        else -> "Loading..."
    }
}

fun main() {
    val status: Status = Status.Loading
    println(statusMessage(status))
}
ALoading...
BSuccess!
CError occurred.
DCompilation error: else branch not allowed with sealed interface
Attempts:
2 left
💡 Hint
Consider how the else branch works with sealed interfaces.
🔧 Debug
advanced
2:00remaining
Why does this when expression cause a compilation error?
Given this sealed class and function, why does the compiler report an error about the when expression not being exhaustive?
Kotlin
sealed class Result {
    data class Success(val data: String) : Result()
    object Failure : Result()
}

fun handle(result: Result): String {
    return when(result) {
        is Result.Success -> "Data: ${result.data}"
    }
}

fun main() {
    println(handle(Result.Failure))
}
ABecause the when expression does not handle the Failure case, so it is not exhaustive.
BBecause sealed classes cannot be used in when expressions without else branch.
CBecause the Failure object is not a subclass of Result.
DBecause the Success data class is missing a default constructor.
Attempts:
2 left
💡 Hint
Check if all subclasses of the sealed class are covered in the when expression.
📝 Syntax
advanced
2:00remaining
Which when expression is exhaustive for this sealed class?
Given the sealed class Command below, which when expression is exhaustive and compiles without error?
Kotlin
sealed class Command {
    object Start : Command()
    object Stop : Command()
    data class Move(val x: Int, val y: Int) : Command()
}
A
when(cmd) {
    is Command.Start -> "Start"
    is Command.Stop -> "Stop"
}
B
when(cmd) {
    is Command.Start -> "Start"
    else -> "Other"
}
C
when(cmd) {
    is Command.Start -> "Start"
    is Command.Stop -> "Stop"
    is Command.Move -> "Move"
}
D
when(cmd) {
    is Command.Move -> "Move"
    else -> "Other"
}
Attempts:
2 left
💡 Hint
An exhaustive when must cover all subclasses or have an else branch.
🚀 Application
expert
2:00remaining
Count how many subclasses are handled in this when expression
Given the sealed class Event and the function below, how many subclasses of Event are handled explicitly in the when expression?
Kotlin
sealed class Event {
    object Click : Event()
    object Hover : Event()
    object Scroll : Event()
    data class KeyPress(val key: Char) : Event()
}

fun handleEvent(event: Event): String {
    return when(event) {
        is Event.Click -> "Clicked"
        is Event.Hover -> "Hovered"
        else -> "Other event"
    }
}
A3
B2
C4
D1
Attempts:
2 left
💡 Hint
Count only the explicit branches, not the else branch.

Practice

(1/5)
1. What is the main benefit of using sealed classes in Kotlin when combined with a when expression?
easy
A. The when expression becomes exhaustive, ensuring all cases are handled.
B. It allows subclassing from any file in the project.
C. It automatically generates getter and setter methods.
D. It makes the class open for inheritance everywhere.

Solution

  1. Step 1: Understand sealed classes restriction

    Sealed classes restrict subclassing to the same file, so all subclasses are known at compile time.
  2. Step 2: Effect on when expression

    This allows the when expression to be exhaustive because the compiler knows all possible subclasses.
  3. Final Answer:

    The when expression becomes exhaustive, ensuring all cases are handled. -> Option A
  4. Quick Check:

    Sealed classes + when = exhaustive check [OK]
Hint: Sealed classes limit subclasses, making when exhaustive [OK]
Common Mistakes:
  • Thinking sealed classes allow subclassing anywhere
  • Confusing sealed classes with data classes
  • Believing sealed classes auto-generate methods
2. Which of the following is the correct syntax to declare a sealed class in Kotlin?
easy
A. sealed class Shape {}
B. open sealed class Shape {}
C. sealed interface Shape {}
D. final sealed class Shape {}

Solution

  1. Step 1: Recall sealed class declaration syntax

    In Kotlin, sealed classes are declared with the keyword sealed followed by class and the class name.
  2. Step 2: Check options for correctness

    sealed class Shape {} uses correct syntax: sealed class Shape {}. open sealed class Shape {} incorrectly adds open, which is not allowed. sealed interface Shape {} uses sealed interface, which is invalid. final sealed class Shape {} uses final sealed class, which is not allowed.
  3. Final Answer:

    sealed class Shape {} -> Option A
  4. Quick Check:

    sealed class declaration = sealed class Shape {} [OK]
Hint: Use only 'sealed class ClassName' to declare sealed classes [OK]
Common Mistakes:
  • Adding 'open' modifier to sealed class
  • Trying to declare sealed interfaces (not allowed)
  • Using 'final' modifier with sealed class
3. Given the sealed class hierarchy below, what will be the output of the describe function when called with Shape.Circle(5.0)?
sealed class Shape {
    data class Circle(val radius: Double) : Shape()
    data class Rectangle(val width: Double, val height: Double) : Shape()
}

fun describe(shape: Shape): String = when(shape) {
    is Shape.Circle -> "Circle with radius ${shape.radius}"
    is Shape.Rectangle -> "Rectangle with width ${shape.width} and height ${shape.height}"
}
medium
A. Rectangle with width 5.0 and height 5.0
B. Compilation error due to missing else branch
C. Shape.Circle
D. Circle with radius 5.0

Solution

  1. Step 1: Identify the input and matching when branch

    The input is Shape.Circle(5.0). The when expression matches is Shape.Circle branch.
  2. Step 2: Evaluate the returned string

    The branch returns the string "Circle with radius 5.0" using the radius property.
  3. Final Answer:

    Circle with radius 5.0 -> Option D
  4. Quick Check:

    Input Circle(5.0) returns "Circle with radius 5.0" [OK]
Hint: Match input type in when to get correct output string [OK]
Common Mistakes:
  • Confusing Circle with Rectangle output
  • Expecting a compilation error due to else missing
  • Returning class name instead of formatted string
4. Consider the following code snippet. What is the error and how can it be fixed?
sealed class Result {
    object Success : Result()
    object Failure : Result()
}

fun handle(result: Result) = when(result) {
    is Result.Success -> "Success"
}
medium
A. Runtime error: Result.Failure is not handled and causes crash.
B. Compilation error: when expression is not exhaustive; add branch for Result.Failure.
C. No error; code runs fine and returns null for Result.Failure.
D. Syntax error: sealed classes cannot have object subclasses.

Solution

  1. Step 1: Identify the sealed class subclasses

    Result has two subclasses: Success and Failure.
  2. Step 2: Check when expression branches

    The when expression only handles Result.Success, missing Result.Failure branch.
  3. Step 3: Understand Kotlin's exhaustiveness check

    Since Result is sealed, when must handle all subclasses or have an else branch. Missing Failure causes compilation error.
  4. Final Answer:

    Compilation error: when expression is not exhaustive; add branch for Result.Failure. -> Option B
  5. Quick Check:

    Sealed class when must cover all subclasses [OK]
Hint: Add all sealed subclasses in when to avoid errors [OK]
Common Mistakes:
  • Assuming runtime error instead of compile error
  • Ignoring missing branches in when
  • Thinking sealed classes can't have object subclasses
5. You have a sealed class Operation with subclasses Add, Subtract, and Multiply. Write a Kotlin function calculate that takes an Operation and two integers, and returns the result of applying the operation. Which of the following implementations correctly uses an exhaustive when expression?
hard
A. fun calculate(op: Operation, a: Int, b: Int): Int = when(op) { is Operation.Add -> a + b else -> 0 }
B. fun calculate(op: Operation, a: Int, b: Int): Int = when(op) { is Operation.Add -> a + b is Operation.Subtract -> a - b }
C. fun calculate(op: Operation, a: Int, b: Int): Int = when(op) { is Operation.Add -> a + b is Operation.Subtract -> a - b is Operation.Multiply -> a * b }
D. fun calculate(op: Operation, a: Int, b: Int): Int = when(op) { is Operation.Multiply -> a * b else -> a + b }

Solution

  1. Step 1: Check all subclasses handled in when

    Operation has Add, Subtract, Multiply. fun calculate(op: Operation, a: Int, b: Int): Int = when(op) { is Operation.Add -> a + b is Operation.Subtract -> a - b is Operation.Multiply -> a * b } handles all three explicitly.
  2. Step 2: Verify exhaustiveness and correctness

    fun calculate(op: Operation, a: Int, b: Int): Int = when(op) { is Operation.Add -> a + b is Operation.Subtract -> a - b is Operation.Multiply -> a * b } covers all subclasses, so when is exhaustive. The other options miss some subclasses or rely on else, which is less clear.
  3. Final Answer:

    fun calculate(op: Operation, a: Int, b: Int): Int = when(op) { is Operation.Add -> a + b is Operation.Subtract -> a - b is Operation.Multiply -> a * b } -> Option C
  4. Quick Check:

    All subclasses covered in when = exhaustive [OK]
Hint: Cover all sealed subclasses explicitly for exhaustive when [OK]
Common Mistakes:
  • Missing some subclasses in when branches
  • Using else instead of explicit branches
  • Returning wrong default values
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard