Kotlin Sealed Classes

Kotlin Sealed Classes

Sealed classes in Kotlin are another new concept we didn’t have in Java, and open another new world of possibilities.

A sealed class allows you to represent constrained hierarchies in which an object can only be of one of the given types.

That is, we have a class with a specific number of subclasses. What we get in the end is a concept very similar to an enum. The difference is that in the enum we only have one object per type, while in the sealed classes we can have several objects of the same class.

This difference will allow objects from a sealed class to keep state. This will bring us some advantages that we’ll see in a moment, and also opens the doors to some functional ideas.

Kotlin Sealed Classes

Implementing a sealed class is actually very simple. Let’s use as an example a set of operations that can be applied to integers.

The implementation would be as follows:

We create a sealed class called Operation, which contains four types of operations: addition, subtraction, multiplication and division.

The good thing about this is that now when expressions will require us to provide branches for all possible types:

If you leave any of the subclasses out, when will complain and it won’t compile. If you implement them all, you don’t need else statement. And in general it won’t be recommended because that way we’re sure that we’re doing the right thing for all of them.

This is also great in case you decide to add a new operation, because it’ll fail at compile time and won’t run. Add a couple more operations: increment and decrement:

You’ll see that the compiler now warns you that there is a problem. Just add branches for these new operations:

You may have noticed I did something different. I used objects instead of classes. This is because if a subclass doesn’t keep state, it can just be an object. All the instances you create for that class would be exactly the same, as they can’t have different state.

Then, in the when expression you can get rid of is for those cases. Here you can just compare the object, as there’s only one instance, you don’t need to check the type of object. It would work too if you keep is for those too.

If you think about it carefully, a sealed class where all subclasses are objects would be the same as an enum.

Moving side effects to a single point

Side effects are a very recurring concept in functional programming. Functional programming relies heavily on the idea that for a given function, same parameters will return the same result.

Any state that is modified may break this assumption. But any program needs to modify states, communicate with input/output elements, etc. So it’s important to spot these operations very specific places in our code that can be easily isolated.

For example, any operations performed on an Android view can be considered a side effect, as the status of the views is being modified and the functions aren’t aware of it.

We could create a sealed class that would allow us to do operations on our views. Based on the idea of our previous example:

Remember: operations that have no state can be objects, because we don’t need different instances.

Now you can create a Ui object that accumulates all interface operations that we want to do over a view, but it won’t execute them until the moment we want.

We’ll have a description of what we want to do, and then we can create a component that executes them:

The Ui class stores a list of operations, and specifies a sum operator that will help make everything a bit cleaner and easier to read. Now we can specify the list of operations that we want to perform:

And then run it. Here I’m just using a run function, but this could be a complete class if required.

Imagine the power that gives you this. Right now all you do is run the operations sequentially, but this could be as complex as required.

This run function could be passed to another function or a class, and the way those operations are run would be totally interchangeable. Remember you can pass functions as arguments.

Conclusion

The concept of the sealed classes is very simple, but it’s the basis of a lot of new ideas you need to get used if you haven’t played with functional programming before.

I must say that I’m not yet able to take the most out of sealed classed due to my knowledge limitations in functional programming.

Happy Coding!

Comments are closed.