Bird
Raised Fist0
Android Kotlinmobile~20 mins

Sealed classes in Android Kotlin - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Sealed Classes Demo
This screen demonstrates how to use sealed classes in Kotlin to represent different states of a network request and display messages accordingly.
Target UI
-------------------------
| Sealed Classes Demo   |
-------------------------
| Status: Idle          |
|                      |
| [Load Success]        |
| [Load Error]          |
| [Load Loading]        |
-------------------------
Create a sealed class named NetworkResult with three subclasses: Success, Error, and Loading.
Display the current status text on the screen.
Add three buttons labeled 'Load Success', 'Load Error', and 'Load Loading'.
When a button is tapped, update the status text to show the corresponding message from the sealed class.
Use Kotlin Android with Jetpack Compose for UI.
Starter Code
Android Kotlin
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      MaterialTheme {
        Surface(modifier = Modifier.padding(16.dp)) {
          // TODO: Add your code here
        }
      }
    }
  }
}

// TODO: Define sealed class NetworkResult here
Task 1
Task 2
Task 3
Task 4
Solution
Android Kotlin
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp

sealed class NetworkResult {
  object Success : NetworkResult()
  object Error : NetworkResult()
  object Loading : NetworkResult()
}

class MainActivity : ComponentActivity() {
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContent {
      MaterialTheme {
        Surface(modifier = Modifier.padding(16.dp)) {
          NetworkResultScreen()
        }
      }
    }
  }
}

@Composable
fun NetworkResultScreen() {
  var result by remember { mutableStateOf<NetworkResult?>(null) }

  val statusText = when (result) {
    is NetworkResult.Success -> "Status: Success! Data loaded."
    is NetworkResult.Error -> "Status: Error! Something went wrong."
    is NetworkResult.Loading -> "Status: Loading... Please wait."
    null -> "Status: Idle"
  }

  Column {
    Text(text = statusText, modifier = Modifier.padding(bottom = 16.dp))

    Button(onClick = { result = NetworkResult.Success }, modifier = Modifier.padding(bottom = 8.dp)) {
      Text("Load Success")
    }

    Button(onClick = { result = NetworkResult.Error }, modifier = Modifier.padding(bottom = 8.dp)) {
      Text("Load Error")
    }

    Button(onClick = { result = NetworkResult.Loading }) {
      Text("Load Loading")
    }
  }
}

We defined a sealed class NetworkResult with three subclasses representing different states: Success, Error, and Loading. This helps us group related states in one type.

In the NetworkResultScreen composable, we use a mutable state variable result to hold the current state. We show a text message based on the current state using a when expression.

Three buttons let the user set the state to Success, Error, or Loading. When clicked, the UI updates automatically to show the new status message. This demonstrates how sealed classes help manage state clearly and safely in Kotlin.

Final Result
Completed Screen
-------------------------
| Sealed Classes Demo   |
-------------------------
| Status: Idle          |
|                      |
| [Load Success]        |
| [Load Error]          |
| [Load Loading]        |
-------------------------
Tapping 'Load Success' changes status text to 'Status: Success! Data loaded.'
Tapping 'Load Error' changes status text to 'Status: Error! Something went wrong.'
Tapping 'Load Loading' changes status text to 'Status: Loading... Please wait.'
Stretch Goal
Add a Reset button that sets the status back to Idle.
💡 Hint
Add another button that sets the state variable to null.

Practice

(1/5)
1. What is the main purpose of a sealed class in Kotlin?
easy
A. To replace interfaces completely
B. To allow unlimited subclassing from any package
C. To create anonymous classes only
D. To restrict class inheritance to a fixed set of subclasses

Solution

  1. Step 1: Understand sealed class inheritance

    A sealed class restricts which classes can inherit from it, limiting subclasses to those defined in the same file.
  2. Step 2: Compare with other class types

    Unlike open classes, sealed classes do not allow unlimited subclassing, ensuring all subclasses are known at compile time.
  3. Final Answer:

    To restrict class inheritance to a fixed set of subclasses -> Option D
  4. Quick Check:

    Sealed class = fixed subclass set [OK]
Hint: Sealed classes limit subclasses to known types only [OK]
Common Mistakes:
  • Thinking sealed classes allow any subclass anywhere
  • Confusing sealed classes with abstract classes
  • Assuming sealed classes create anonymous classes
2. Which of the following is the correct syntax to declare a sealed class named Result in Kotlin?
easy
A. sealed Result class {}
B. sealed class Result {}
C. class sealed Result {}
D. sealed interface Result {}

Solution

  1. Step 1: Recall sealed class declaration syntax

    The keyword sealed precedes class followed by the class name and braces.
  2. Step 2: Check each option

    sealed class Result {} matches the correct syntax. Options B and C have wrong keyword order. sealed interface Result {} declares a sealed interface, not a sealed class.
  3. Final Answer:

    sealed class Result {} -> Option B
  4. Quick Check:

    sealed class syntax = "sealed class Name {}" [OK]
Hint: sealed class always starts with 'sealed class' keywords [OK]
Common Mistakes:
  • Swapping 'sealed' and 'class' keywords
  • Using 'sealed interface' instead of 'sealed class'
  • Omitting braces after class name
3. Given the sealed class and when expression below, what will be printed?
sealed class Response {
  object Success : Response()
  object Error : Response()
}

fun handle(response: Response) {
  when(response) {
    is Response.Success -> println("Success")
    is Response.Error -> println("Error")
  }
}

handle(Response.Success)
medium
A. Nothing is printed
B. Error
C. Success
D. Compile-time error

Solution

  1. Step 1: Identify the passed object type

    The function is called with Response.Success, which matches the first when branch.
  2. Step 2: Check the when branches

    The when expression prints "Success" for Response.Success and "Error" for Response.Error.
  3. Final Answer:

    Success -> Option C
  4. Quick Check:

    Response.Success triggers "Success" print [OK]
Hint: Match sealed subclasses exactly in when to get correct output [OK]
Common Mistakes:
  • Confusing Success and Error outputs
  • Forgetting to call the function with correct subclass
  • Expecting compile error due to sealed class
4. What is wrong with this sealed class declaration?
sealed class State {}
class Loading : State()
class Success : State()
class Error : State()
medium
A. Subclasses must be declared inside the sealed class file
B. Sealed classes cannot have subclasses
C. Subclasses must be objects, not classes
D. Sealed class must be abstract

Solution

  1. Step 1: Recall sealed class subclass rules

    All subclasses of a sealed class must be declared in the same file as the sealed class.
  2. Step 2: Analyze the code snippet

    The subclasses Loading, Success, Error are declared separately after the sealed class. This violates the rule because direct subclasses of a sealed class must be declared in the same file as the sealed class.
  3. Final Answer:

    Subclasses must be declared inside the sealed class file -> Option A
  4. Quick Check:

    Sealed subclasses must be in same file [OK]
Hint: Keep all sealed subclasses in the same file [OK]
Common Mistakes:
  • Declaring subclasses in different files
  • Thinking sealed classes cannot have subclasses
  • Confusing sealed classes with abstract classes
5. You want to represent a network request state with a sealed class NetworkState having Loading, Success with data, and Error with message. Which is the best way to define Success and Error subclasses?
hard
A. Use data classes with properties inside the sealed class
B. Use object declarations for all subclasses
C. Use abstract classes for Success and Error
D. Use interfaces for Success and Error

Solution

  1. Step 1: Understand subclass data needs

    Success needs to hold data, and Error needs to hold a message, so they require properties.
  2. Step 2: Choose subclass type

    Data classes are ideal for subclasses with properties because they provide equals, hashCode, and toString automatically.
  3. Final Answer:

    Use data classes with properties inside the sealed class -> Option A
  4. Quick Check:

    Data classes hold data in sealed subclasses [OK]
Hint: Use data classes for sealed subclasses with data [OK]
Common Mistakes:
  • Using object for subclasses needing data
  • Using abstract classes unnecessarily
  • Using interfaces instead of sealed subclasses
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