Intuit Engineering
Published in

Intuit Engineering

Kotlin Sealed Classes in Action

Enums are a common convention in coding languages to prevent coding errors. When coding, enums allow me to restrict the domain in my code to just those predefined enumerated types. In other words, an enumerated type is a data type with a set of named constants representing the type. As an example, , , , and are enumerations of the compass direction type. These are a group of constants where the variations are known at compile time.

By using enums, I can increase compile-time checking and decrease coding errors by passing an invalid type. When the enumerations are predefined, I am restricted to those specific types rather than loosely allowing any constant value. While enums are very helpful in this regard, there are some limitations to an enum and that’s where Kotlin sealed classes come into the picture. I like to think of sealed classes as “super” enums. The “super” aspect comes from two key capabilities:

  1. Saving state in the subclasses of the sealed class
  2. Allowing different types of objects inside the subclasses of the sealed class

Let’s say I have a very simple Android application. Depending on some internal logic, I need to display a screen of one of the following states:

  • Loading page: loading spinner animation
  • Error page: text showing the error message
  • Data page: data about my pet seal

For simplicity, I could just create an enum of the three different types and then get the data to be displayed for that status’ page. In this case, each enum is a constant value.

However, what if I wanted to store values inside the enum constants. I could do something like this, but note that the enums are not necessarily “stateful”.

This allows me to relate the specific strings to the enum types, but I need different data content to be associated with the enum instead of just “Displaying data”. It needs to change based on which seal pet I am showing in the application. Also, I really want different enum types to contain varying types inside of them. The type doesn’t really need any data inside of it, as it will just be showing a loading animation. The type would need a string to hold the error message which could vary depending on the error. Lastly, the type should hold a type with information about the seal’s name, age, and honk type.

This leads us to a sealed type for the seals!

Note that we have no state to store in the type. Therefore, we can make the class a singleton to avoid unnecessary allocations. In Kotlin, this is done through the object keyword in the class definition. In the code above, you can see we made the type a singleton with the object Kotlin keyword.

Now I have a nice sealed class with some subclasses of different types that are holding state. I can take advantage of them by using the when expression to set the view appropriate to the screen state. Note that the when expression is exhaustive on the sealed class type and does not require an else branch.

Now I have clean and concise code using a sealed class!

--

--

Thoughts from Intuit on tech, data, and the culture that powers today's innovation.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store