avatarGabriel Shanahan

Summary

The provided content introduces sealed classes and interfaces in Kotlin, emphasizing their importance in software design and their benefits in enabling exhaustive when expressions and preventing runtime errors.

Abstract

The article "Sealed Hierarchies: Introduction" provides an overview of sealed classes and interfaces in Kotlin, which are also known as sum or union types. These constructs define a fixed hierarchy of types at compile time, ensuring that no external subclasses can be added, particularly useful in library code distribution. The author, Gabriel Shanahan, positions sealed hierarchies as a powerful tool for enhancing programming practices, suggesting that they can lead to significant improvements in code design and safety. The article is part of the "Kotlin Primer," intended to facilitate Kotlin adoption in Java-centric organizations. It highlights the practical benefits of sealed hierarchies, such as enabling exhaustive when expressions without the need for an else branch, and teases more profound advantages that will be discussed in subsequent chapters. The author expresses a strong belief in the transformative potential of these concepts, promising to reveal insights that extend beyond Kotlin and can elevate the reader's programming skills in general.

Opinions

  • The author believes that the concepts related to sealed hierarchies are crucial for readers to understand and can lead to new design paradigms and improved programming skills.
  • Sealed hierarchies are likened to enums in the type domain, with the distinction that they allow multiple instances of their members, unlike enums which are limited to single instances.
  • The author suggests that by restricting the extensibility of a hierarchy, developers gain the ability to make more assumptions, which can lead to safer and more robust code.
  • The article posits that the commonly highlighted benefit of sealed hierarchies (compiler-assisted exhaustive when expressions) is not the most significant advantage, implying that there are deeper, less obvious benefits to be explored in future chapters.
  • The author expresses gratitude to Etnetera a.s. for supporting the creation of the "Kotlin Primer," indicating a collaborative effort behind the educational resource.

Sealed Hierarchies: Introduction

An introduction to sealed classes and sealed interfaces, also called sum or union types, and a teaser for what they’re actually good for.

— — — — — — — — — — — — — — —

THE CURRENT VERSION OF THIS ARTICLE IS PUBLISHED HERE.

— — — — — — — — — — — — — — —

Tags: #KOTLIN FEATURE

This article is part of the Kotlin Primer, an opinionated guide to the Kotlin language, which is indented to help facilitate Kotlin adoption inside Java-centric organizations. It was originally written as an organizational learning resource for Etnetera a.s. and I would like to express my sincere gratitude for their support.

It is recommended to read the Introduction before moving on. Check out the Table of Contents for all articles.

Before we start, let me say that I honestly believe that the concepts discussed in the following chapters are among the most important things you can take away from the Primer — concepts which will open up your mind to new ways of designing, even outside of Kotlin, and make you a better programmer, period.

In this chapter, we will briefly discuss the concept of a sealed hierarchy, while the next chapters will delve into the techniques I just teased. Let’s go.

A sealed class (or sealed interface) represents a hierarchy which is determined at compile time. No other subclasses may appear after the module with the sealed hierarchy is compiled. For example, if your code is distributed as a library, users can’t extend your sealed hierarchy in their own code. Thus, each instance of a sealed class has a type from a limited set that is known when this class is compiled. Such a hierarchy is often called a union or sum type — a type that is a union (or sum) of a finite number of possibilities.

A sealed class or interface is declared with sealed class or sealed interface.

In some sense, sealed hierarchies are similar to enum classes: the set of values for an enum type is also restricted, but each enum constant exists only as a single instance, whereas a member of a sealed hierarchy can have multiple instances. It could be said that sealed hierarchies are the equivalent of enums in the type domain. If you created a sealed hierarchy consisting entirely of objects (i.e. singletons), you would have effectively created an enum.

There are rules to using sealed hierarchies that you should review in the docs. The most important one is that direct subclasses of sealed classes and interfaces must be declared in the same package.

You might be wondering what good this could possibly do us — after all, how does limiting usability have any benefits? Well, generally speaking, whenever you restrict something, it also means that you expand the number of assumptions you can make about it, and this often opens up doors that were closed before.

In the case of sealed hierarchies, one of the immediate practical benefits is that the compiler can perform assumptions in when expressions that it can't otherwise:

Normally, we would need an else branch, but since Expression is a sealed hierarchy, the compiler knows that, by definition, there can’t be any other subclasses other than the ones present at compile time. As a consequence, we can omit the else branch entirely.

This is often presented as the main benefit of sealed hierarchies, and things are left at that. I disagree with this treatment strongly — there are benefits which are immeasurably more important, less obvious, and are a direct consequence of what we just learned.

That’s what we’ll be talking about in the next chapters.

Go back to Delegation — Summary, jump to the Table of Contents, or continue to Safely Emulating Dynamic Dispatch.

Join me in Etnetera
Kotlin
Java
Programming
Functional Programming
Object Oriented
Recommended from ReadMedium