Guide to Sealed Classes in Kotlin for Improved Code Organization

Guide to Sealed Classes in Kotlin for Improved Code Organization

In the last article, we covered data classes in Kotlin. We saw how they simplify class creation and make it faster with less coding. Now, let's explore Sealed Classes.

Sealed Classes in Kotlin are a specialized form of abstract classes. They limit subclassing, giving you more control. This article will explain what sealed classes are, how they benefit you in Kotlin, and the best ways to use them.

Sealed Classes in Kotlin are a type of abstract class that can't be initiated directly, with abstract members. They limit subclassing, ensuring a class only has a limited, well-defined set of subclasses. This improves type-safety and helps write error-free code.

In this article, we'll cover the basics of Sealed Classes: syntax, constructors, and subclass restrictions. We'll also see how Sealed Classes can be used in when expressions for a more controlled, type-safe handling of cases. Whether you're new to Kotlin or a seasoned developer, you'll gain valuable insights on using Sealed Classes effectively.

Poperties and Overview

Sealed Classes in Kotlin limit the type hierarchy. They're like restricted abstract classes, having constructors and the ability to extend classes. But, unlike open or abstract classes, they cannot be inherited outside their file or package.

An example of a Sealed Class in Kotlin:

sealed class Error {
    abstract val message: String
}

The visibility of Sealed Class constructors is based on the visibility of the class. If the Sealed Class is private, its constructors will also be private. If it's internal, the constructors will be internal and so on.

Sealed classes in Kotlin have a limitation on inheritance. The direct descendants of a sealed class must be located in the same file or package as the sealed class itself. It's not possible to create a subclass of a sealed class in a different file or package.

Here's an illustration of two subclasses of the Error sealed class in the same file:

data class FileReadError(override val message: String, val file: String) : Error()

data class DatabaseError(override val message: String, val source: String) : Error()

Additionally, the subclasses of a sealed class must have a fully qualified name and cannot be defined as local or anonymous objects.

Control Flow

The usage of sealed classes in Kotlin offers improved control over control flow statements. One of the key advantages of sealed classes is demonstrated through their utilization in when expressions.

when expressions in Kotlin are comparable to switch statements in other programming languages. They let you inspect the class type of an object and perform different operations based on its type. Unlike switch statements, it is mandatory to include an else clause to cater to cases not covered in traditional switch statements.

With sealed classes, it is possible to verify that the when statement covers all cases, eliminating the need for an else clause. Consider the following example:

sealed class Error
class FileReadError : Error()
class DatabaseError : Error()
class RuntimeError : Error()

fun log(e: Error) = when(e) {
    is FileReadError -> { println("Error while reading file") }
    is DatabaseError -> { println("Error reading from database") }
    is RuntimeError ->  { println("Runtime error") }
    // the `else` clause is not required because all the cases are covered
}

In the example, Error is defined as a sealed class, with subclasses FileReadError, DatabaseError, and RuntimeError. The when expression within the log function checks the type of error and prints a corresponding message for each case.

Sealed classes in a when expression offer clear and reliable code, as all cases are accounted for, and there's no need for an else clause.

Conclusion

Sealed classes in Kotlin are a valuable tool for better type safety and control flow in your code. When used with when expressions, they restrict the objects that can be passed and make it simpler to guarantee all cases are handled. Additionally, sealed classes enforce proper naming conventions and keep subclasses in the same package, helping maintain code integrity and readability. Whether you are a beginner or an experienced developer, sealed classes are a must-have for writing superior code in Kotlin.

Happy Coding.