OOP model
- Kotlin course
- Intermediate
- Lesson 113/116
- 6 min
Set up the class hierarchy and interfaces.
Sealed class: Category
To sort books into categories you will define a sealed class. A sealed class sets up a hierarchy with a limited number of subtypes; it provides exhaustiveness in when expressions. Here you will use two categories: Fiction and NonFiction.
sealed class Category {
abstract fun label(): String
}
object Fiction : Category() {
override fun label() = "Fiction"
}Each subtype (an object) inherits from Category and implements the label method. An object declares a singleton; there is exactly one instance per category. The Book class will get a category: Category property and format will show the category label.
Adding category to Book
The Book class gets a category: Category property. The format method also shows the category label: "$title - $author ($year) [${category.label()}]". So the book type appears in the output too.
val b = Book("Crime and Punishment", "Dostoyevsky", 1866, Fiction)
println(b.format())
// Crime and Punishment - Dostoyevsky (1866) [Fiction]Here the Fiction object is given as the category; label() returns "Fiction". Thanks to the sealed class, the compiler knows that Category is only Fiction and NonFiction; this provides safety in when expressions. To add a new category later, just add a new object to the sealed class.
Practice Combine Category sealed class and Book
The provided Book class already includes the category: Category property. Define sealed class Category; inside it add abstract fun label(): String. Define object Fiction : Category() and object NonFiction : Category(); each overrides label() (Fiction returns "Fiction", NonFiction returns "Non-fiction"). In main create one Fiction and one NonFiction book and print with println(b.format()).
Starter code
data class Book(val title: String, val author: String, val year: Int, val category: Category) {
fun format(): String = "$title - $author ($year) [${category.label()}]"
}
// Define Category sealed class: Fiction and NonFiction object subtypes
// label() method: Fiction returns "Fiction", NonFiction returns "Non-fiction"
// main: create one Fiction and one NonFiction book and print format output
fun main() {
// write here
}Sample solution
data class Book(val title: String, val author: String, val year: Int, val category: Category) {
fun format(): String = "$title - $author ($year) [${category.label()}]"
}
sealed class Category {
abstract fun label(): String
}
object Fiction : Category() {
override fun label() = "Fiction"
}
object NonFiction : Category() {
override fun label() = "Non-fiction"
}
fun main() {
val b1 = Book("Crime and Punishment", "Dostoyevsky", 1866, Fiction)
val b2 = Book("Sapiens", "Harari", 2011, NonFiction)
println(b1.format())
println(b2.format())
}Expected output
Crime and Punishment - Dostoyevsky (1866) [Fiction] Sapiens - Harari (2011) [Non-fiction]
Questions and answers
Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.
1 What advantage does a sealed class provide?
- Unlimited subtypes
- Less memory usage
- Faster compilation
- Bounded subtypes and when exhaustiveness Correct answer
Explanation: A sealed class provides bounded subtypes and exhaustiveness in when.
2 Declare a sealed class
____ class Category {
abstract fun label(): String
}
sealed class Category {
abstract fun label(): String
}
Explanation: sealed class Category sets up a bounded hierarchy.
3 Match the Category parts
| Term | Meaning |
|---|---|
sealed class Category |
Bounded hierarchy |
object Fiction |
Singleton subtype |
override fun label() |
Label method |
"Fiction" |
Fiction label |