Sealed vs Enum Classes in Kotlin

Sealed vs Enum Classes in Kotlin

Kotlin is a statically typed programming language designed to improve the productivity and readability of code. It provides several features that simplify the development process, including sealed classes and enum classes.

These two types of classes serve different purposes and can be used in different scenarios. In this article, we will explore the differences between sealed classes and enum classes in Kotlin and how they can be used to improve the design and implementation of your code.

Sealed classes:

They are a type of class in Kotlin that are used to represent a closed(fixed) set of cases. They allow you to restrict the possible types of a value to a predefined set of cases, making it easier to handle cases that are known at compile time.

A sealed class is defined using the sealed keyword, followed by the class definition. For example:

sealed class Shape {
    class Circle(val radius: Double) : Shape()
    class Rectangle(val width: Double, val height: Double) : Shape()
}
class Triangle(val base: Double, val height: Double) : Shape()

In this example, we have defined a sealed class Shape that contains three subclasses: Circle, Rectangle, and Triangle. The sealed class acts as a parent class for these subclasses, which represent different types of shapes.

When to Use Sealed:

Sealed classes are useful when you need to represent a closed set of cases, where the set of cases is known at compile time. They are particularly useful when you are using a when expression to check each possible case.

For example, consider the following code that calculates the area of a shape:

fun calculateArea(shape: Shape) = when(shape) {
    is Shape.Circle -> Math.PI * shape.radius * shape.radius
    is Shape.Rectangle -> shape.width * shape.height
    is Shape.Triangle -> shape.base * shape.height / 2
}

In this example, the when expression checks each possible case of the sealed class Shape, and performs the appropriate calculation based on the type of shape. Because the set of cases is known at compile time, the compiler will alert you if you have not handled every possible case. This makes it easier to catch errors and ensure that your code is correct.

Special Cases in Sealed Classes:

One of the advantages of sealed classes is that they can have custom behavior for each case. For example, you can add properties or methods to each subclass, making it easier to handle specific cases.

In addition, sealed classes also have the following special cases:

  • Sealed classes can only have subclasses that are declared within the same file as the sealed class. This helps to ensure that the set of cases is closed and that new cases cannot be added without modifying the existing code.

  • When using a when expression with a sealed class, you do not need to include a else case, as the compiler will alert you if you have not handled every possible case.

Enum Classes:

They are used to represent a fixed set of "values", where each value is called an enum constant. Enum classes are used to define a set of possible values that are known at compile time, and can be used to simplify code and improve readability.

For example:

enum class Color {
    RED, GREEN, BLUE
}

In this example, we have defined an enum class Color that contains three enum constants: RED, GREEN, and BLUE. The enum class acts as a type for these constants, allowing us to use them in our code.

When to Use Enum Classes

Enum classes are useful when you need to represent a fixed set of values, where each value has a distinct identity. They are particularly useful when you need to check for specific values or use values as switch cases in a when expression.

For example, consider the following code that sets the background color of a view based on a Color enum:

fun setBackgroundColor(view: View, color: Color) = when(color) {
    Color.RED -> view.setBackgroundColor(Color.RED)
    Color.GREEN -> view.setBackgroundColor(Color.GREEN)
    Color.BLUE -> view.setBackgroundColor(Color.BLUE)
}

In this example, the when expression checks each possible value of the Color enum, and sets the background color of the view accordingly.

Special Cases in Enum Classes

Enum classes have the following special cases:

  • Enum constants are defined as objects, which means that each constant is a singleton object. This makes it easy to compare values using the == operator, as it compares object references.

  • Enum classes can have properties and methods, which allow you to add custom behavior to each constant. For example, you could add a description property to the Color enum to provide a more descriptive name for each color.

  •       enum class Color(val description: String) {
              RED("Red"),
              GREEN("Green"),
              BLUE("Blue");
    
              override fun toString() = description
          }
    
  • Enum classes can be used with the when expression to switch between different values. This makes it easy to handle different cases based on the value of the enum, and the compiler will alert you if you have not handled every possible value.

What to use?

The decision of whether to use an enum class or a sealed class in Kotlin depends on the requirements of your code.

Enum classes are best used when you need to represent a fixed set of values that are known at compile time, and where each value has a distinct identity. Enum classes are useful for defining simple, closed sets of values that can be used as cases in a when expression.

Sealed classes, on the other hand, are best used when you need to represent a more complex set of values, where each value is a different type of object. Sealed classes are useful for defining open sets of values, where new values can be added in the future without changing the existing code.

For example, consider the following code that models a shape:

enum class Shape {
    CIRCLE, RECTANGLE, SQUARE
}

In this example, the Shape enum class represents a fixed set of shapes that are known at compile time and the when the expression can be used to switch between different shapes.

Now, consider the following code that models a mathematical expression:

sealed class Expression
class Add(val left: Expression, val right: Expression): Expression()
class Multiply(val left: Expression, val right: Expression): Expression()
class Const(val value: Int): Expression()

In this example, the Expression the sealed class represents a more complex set of mathematical expressions, where each expression is a different type of object. The Expression sealed class is open, meaning that new types of expressions can be added in the future without changing the existing code.

In conclusion, the choice between using an enum class or a sealed class depends on the specific use case you have in mind. Enum classes are best used for simple, closed sets of values that are known at compile time, while sealed classes are best used for more complex, open sets of values to be made from subclasses of sealed class type.

I hope you found this helpful. If yes, then do FOLLOW me for more Android-related content.

#androidWithSagar #xDaysOfAndroid #android #androiddevelopment