Sealed classes for restricted hierarchies in Kotlin - Time & Space Complexity
We want to understand how the time it takes to work with sealed classes changes as we add more subclasses or data.
How does the program's work grow when using sealed classes in Kotlin?
Analyze the time complexity of the following code snippet.
sealed class Shape {
data class Circle(val radius: Double) : Shape()
data class Rectangle(val width: Double, val height: Double) : Shape()
object NotAShape : Shape()
}
fun area(shape: Shape): Double = when(shape) {
is Shape.Circle -> Math.PI * shape.radius * shape.radius
is Shape.Rectangle -> shape.width * shape.height
Shape.NotAShape -> 0.0
}
This code defines a sealed class with a few subclasses and a function that calculates area based on the shape type.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: The
whenexpression checks the type of the shape once. - How many times: Exactly once per call to
area, no loops or recursion inside.
Since the function checks the shape type once, the work stays the same no matter how many subclasses exist.
| Input Size (n) | Approx. Operations |
|---|---|
| 1 | 1 check |
| 10 | 1 check |
| 100 | 1 check |
Pattern observation: The time to compute area does not grow with the number of subclasses because the check is direct and fixed.
Time Complexity: O(1)
This means the time to find the area stays constant no matter how many subclasses the sealed class has.
[X] Wrong: "Adding more subclasses to a sealed class makes the area function slower because it has to check all of them."
[OK] Correct: The when expression is compiled to a direct check, so it does not loop through subclasses but jumps directly to the right case.
Understanding how sealed classes work helps you explain how Kotlin handles restricted hierarchies efficiently, showing you know both design and performance.
"What if the area function used a list of shapes and calculated the total area by looping through them? How would the time complexity change?"
Practice
sealed classes in Kotlin?Solution
Step 1: Understand sealed class inheritance rules
Sealed classes restrict subclassing to the same file, limiting which classes can extend them.Step 2: Compare options with sealed class purpose
Only To restrict which classes can inherit from it, all in the same file correctly describes this restriction; others describe unrelated features.Final Answer:
To restrict which classes can inherit from it, all in the same file -> Option CQuick Check:
Sealed classes restrict inheritance = A [OK]
- Thinking sealed classes prevent instantiation
- Confusing sealed classes with abstract classes
- Believing sealed classes allow open inheritance
Shape in Kotlin?Solution
Step 1: Recall sealed class declaration syntax
Sealed classes are declared with the keywordsealed classfollowed by the name and body.Step 2: Check each option's correctness
sealed class Shape {} matches the correct syntax. open sealed class Shape {} wrongly combinesopenandsealed. sealed interface Shape {} usessealed interfacewhich is invalid. abstract sealed class Shape {} wrongly combinesabstractandsealed.Final Answer:
sealed class Shape {} -> Option DQuick Check:
Correct sealed class syntax = D [OK]
- Adding 'open' or 'abstract' keywords with sealed
- Using 'sealed interface' instead of 'sealed class'
- Forgetting curly braces after class name
sealed class Result {
data class Success(val data: String) : Result()
object Failure : Result()
}
fun handle(result: Result) = when(result) {
is Result.Success -> "Data: ${result.data}"
is Result.Failure -> "Failed"
}
println(handle(Result.Success("OK")))What is the output when this code runs?
Solution
Step 1: Understand sealed class and when expression
The sealed classResulthas two subclasses:SuccessandFailure. Thewhenexpression covers both cases without else.Step 2: Trace the function call with Success("OK")
The argument isResult.Success("OK"), so the first branch matches, returning "Data: OK".Final Answer:
"Data: OK" -> Option AQuick Check:
Sealed class when covers all cases = "Data: OK" [OK]
- Thinking else branch is required for sealed classes
- Confusing Success and Failure outputs
- Expecting runtime errors from sealed classes
sealed class Animal class Dog : Animal() class Cat : Animal()
Why does this code cause a compilation error?
Solution
Step 1: Recall sealed class subclass rules
Sealed classes restrict subclasses to be declared in the same file.Step 2: Identify the error cause
Dog and Cat are subclasses but declared outside the sealed class file, causing compilation error.Final Answer:
Subclasses Dog and Cat must be declared in the same file as Animal -> Option BQuick Check:
Sealed subclasses must be in same file = B [OK]
- Thinking sealed classes forbid any subclassing
- Believing subclasses must be sealed too
- Confusing sealed with abstract class rules
Admin, Guest, and Member. Which approach correctly uses sealed classes to restrict roles and safely handle all cases?Solution
Step 1: Use sealed class to restrict subclasses
sealed class UserRole { object Admin : UserRole() object Guest : UserRole() object Member : UserRole() } fun describe(role: UserRole) = when(role) { is UserRole.Admin -> "Admin user" is UserRole.Guest -> "Guest user" is UserRole.Member -> "Member user" } declares a sealed class with all subclasses as objects inside the same file, restricting roles properly.Step 2: Check safe handling with exhaustive when
Thewhenexpression covers all subclasses without else, ensuring safe handling.Final Answer:
sealed class UserRole { object Admin : UserRole() object Guest : UserRole() object Member : UserRole() } fun describe(role: UserRole) = when(role) { is UserRole.Admin -> "Admin user" is UserRole.Guest -> "Guest user" is UserRole.Member -> "Member user" } -> Option AQuick Check:
Sealed class + exhaustive when = safe fixed roles [OK]
- Using open or abstract classes without sealing
- Missing exhaustive when branches
- Using sealed interface incorrectly
Ready to prove it?
Pass the test and this pattern moves unknown
