A data class automatically generates equals(), hashCode(), toString(), and a copy() method — ideal for simple models:
data class User(val id: Int, val name: String, val email: String)
val user1 = User(1, "Ada", "ada@example.com")
val user2 = user1.copy(name = "Ada Lovelace") // copies with one field changed
println(user1 == user2) // false — structural equality, comparing all fields
Sealed classes
A sealed class restricts a type hierarchy to a known, closed set of subclasses — ideal for representing UI state or a network result, where you want the compiler to force you to handle every case:
sealed class NetworkResult<out T> {
data class Success<T>(val data: T) : NetworkResult<T>()
data class Error(val message: String) : NetworkResult<Nothing>()
object Loading : NetworkResult<Nothing>()
}
fun handleResult(result: NetworkResult<List<User>>) {
when (result) {
is NetworkResult.Success -> showUsers(result.data)
is NetworkResult.Error -> showError(result.message)
NetworkResult.Loading -> showSpinner()
} // no 'else' needed — the compiler knows these are ALL the possible cases
}
This pattern will come back constantly once you get to networking and ViewModel state later in this course.
- Image
- SKU
- Rating
- Price
- Stock
- Availability
- Add to cart
- Description
- Content
- Weight
- Dimensions
- Additional information