Kotlin - Enum Classes

Enum Classes in Kotlin 

Kotlin, as a modern statically-typed language, provides several powerful features to simplify and enhance code readability and robustness. One such feature is the enum class. Enumerations, or enums, are a special kind of class that represents a group of predefined constants. Enum classes in Kotlin offer type safety, the ability to associate properties and methods with constants, and integration with Kotlin’s powerful object-oriented and functional programming features.

What is an Enum Class?

An enum class in Kotlin is a special type of class used to represent a fixed set of constants. This is useful when a variable can only hold a limited set of values, such as days of the week, states in a process, directions, or months of the year. Kotlin’s enum classes are more advanced than traditional enums found in languages like Java, C, or C++ as they support methods, properties, and constructors.

enum class Direction {
    NORTH, SOUTH, EAST, WEST
}

In this simple example, Direction is an enum class that has four constants: NORTH, SOUTH, EAST, and WEST.

Basic Syntax of Enum Classes

enum class EnumName {
    CONSTANT1,
    CONSTANT2,
    CONSTANT3
}

Each value defined in the enum is an object. You can access them just like any other object.

fun main() {
    val dir = Direction.NORTH
    println("Direction is: $dir")
}

Enum Classes with Properties and Methods

In Kotlin, you can associate properties and methods with enum constants by defining a constructor and adding methods.

enum class Planet(val mass: Double, val radius: Double) {
    EARTH(5.972E24, 6.371E6),
    MARS(6.417E23, 3.390E6);

    fun surfaceGravity(): Double {
        val G = 6.67430e-11
        return G * mass / (radius * radius)
    }
}

Usage

fun main() {
    val gravity = Planet.EARTH.surfaceGravity()
    println("Surface gravity on Earth is $gravity")
}

Each enum constant is an object that can have properties and functions. The constructor parameters are passed to each object, and you can call functions just like with regular class instances.

Initializing Enum Constants with Custom Behavior

Enum constants can override methods if they need to provide custom behavior. This is useful when each enum instance behaves differently.

enum class Operation {
    PLUS {
        override fun apply(x: Int, y: Int): Int = x + y
    },
    MINUS {
        override fun apply(x: Int, y: Int): Int = x - y
    };

    abstract fun apply(x: Int, y: Int): Int
}

In the example above, each constant overrides the abstract function apply() with a different implementation.

Using the Enum

fun main() {
    val op = Operation.PLUS
    println("5 + 3 = ${op.apply(5, 3)}")
}

Working with Enum Constants

Accessing All Enum Values

Kotlin provides a built-in values() method to access all constants of an enum.

enum class Color {
    RED, GREEN, BLUE
}

fun main() {
    val colors = Color.values()
    for (color in colors) {
        println(color)
    }
}

Accessing Enum by Name

Use the valueOf() method to get a constant by its name.

val color = Color.valueOf("RED")
println(color) // Output: RED

Enum Properties: name and ordinal

  • name: Returns the name of the enum constant as a String.
  • ordinal: Returns the position of the constant in the declaration, starting from 0.
val color = Color.GREEN
println(color.name)    // Output: GREEN
println(color.ordinal) // Output: 1

Using Enum Classes in When Expressions

Enum classes are particularly useful in when expressions.

fun describe(color: Color): String {
    return when (color) {
        Color.RED -> "Color is Red"
        Color.GREEN -> "Color is Green"
        Color.BLUE -> "Color is Blue"
    }
}

Sealed Classes vs. Enum Classes

Both sealed classes and enum classes are used to represent restricted hierarchies, but they are different:

Feature Enum Class Sealed Class
Constant values Fixed set of instances Can have subclasses defined anywhere in the same file
Type hierarchy Cannot extend other enums Supports class hierarchy
Inheritance Implicitly inherits from Enum Inherits from Sealed class

Serialization and Enum Classes

When using serialization libraries (e.g., kotlinx.serialization or Gson), enum classes are automatically supported as long as they follow standard conventions.

@Serializable
enum class Status {
    SUCCESS, ERROR, LOADING
}

Enum Constants as Anonymous Classes

Each enum constant can be an anonymous class that implements abstract members of the enum class.

enum class Signal {
    RED {
        override fun action() = "Stop"
    },
    GREEN {
        override fun action() = "Go"
    },
    YELLOW {
        override fun action() = "Wait"
    };

    abstract fun action(): String
}

This pattern is useful for polymorphic behavior.

Enum in Data Modeling

Enum classes are great tools for modeling states in finite state machines, fixed status codes, or user roles.

enum class UserRole(val level: Int) {
    ADMIN(3),
    MODERATOR(2),
    USER(1)
}

Enums ensure type safety and prevent invalid values being assigned.

Enum Class Limitations

  • Cannot extend other classes (because enum already inherits from Kotlin’s Enum).
  • Cannot be declared as data classes.
  • Cannot be generic.
  • Cannot be nested inside functions.

EnumSet and EnumMap (Using Java Interop)

Kotlin can interoperate with Java, so you can use Java's EnumSet and EnumMap when needed.

val enumSet = EnumSet.of(Color.RED, Color.GREEN)
println(enumSet)

These are efficient collections for enums, offering constant-time performance.

Best Practices

  • Use enums for small, well-defined sets of constants.
  • Avoid putting too much logic inside enums. Keep them lightweight.
  • Use properties and methods when enum constants have associated data or behavior.
  • Use when expressions for readable branching logic with enums.
  • Prefer enums over sealed classes for simple constant sets.

Kotlin’s enum classes are a powerful feature that combine simplicity and expressiveness. They allow developers to define a set of constants with their own behavior and data. Enums make your code more readable, safe, and idiomatic. Whether you are modeling directions, user roles, states, or operations, enum classes are a robust choice that integrates well with Kotlin’s language features.

With support for constructors, methods, interfaces, and interoperability with Java, enum classes in Kotlin offer much more than traditional enumerations, making them a key tool in any Kotlin developer’s toolbox.

Beginner 5 Hours

Enum Classes in Kotlin 

Kotlin, as a modern statically-typed language, provides several powerful features to simplify and enhance code readability and robustness. One such feature is the enum class. Enumerations, or enums, are a special kind of class that represents a group of predefined constants. Enum classes in Kotlin offer type safety, the ability to associate properties and methods with constants, and integration with Kotlin’s powerful object-oriented and functional programming features.

What is an Enum Class?

An enum class in Kotlin is a special type of class used to represent a fixed set of constants. This is useful when a variable can only hold a limited set of values, such as days of the week, states in a process, directions, or months of the year. Kotlin’s enum classes are more advanced than traditional enums found in languages like Java, C, or C++ as they support methods, properties, and constructors.

enum class Direction { NORTH, SOUTH, EAST, WEST }

In this simple example, Direction is an enum class that has four constants: NORTH, SOUTH, EAST, and WEST.

Basic Syntax of Enum Classes

enum class EnumName { CONSTANT1, CONSTANT2, CONSTANT3 }

Each value defined in the enum is an object. You can access them just like any other object.

fun main() { val dir = Direction.NORTH println("Direction is: $dir") }

Enum Classes with Properties and Methods

In Kotlin, you can associate properties and methods with enum constants by defining a constructor and adding methods.

enum class Planet(val mass: Double, val radius: Double) { EARTH(5.972E24, 6.371E6), MARS(6.417E23, 3.390E6); fun surfaceGravity(): Double { val G = 6.67430e-11 return G * mass / (radius * radius) } }

Usage

fun main() { val gravity = Planet.EARTH.surfaceGravity() println("Surface gravity on Earth is $gravity") }

Each enum constant is an object that can have properties and functions. The constructor parameters are passed to each object, and you can call functions just like with regular class instances.

Initializing Enum Constants with Custom Behavior

Enum constants can override methods if they need to provide custom behavior. This is useful when each enum instance behaves differently.

enum class Operation { PLUS { override fun apply(x: Int, y: Int): Int = x + y }, MINUS { override fun apply(x: Int, y: Int): Int = x - y }; abstract fun apply(x: Int, y: Int): Int }

In the example above, each constant overrides the abstract function apply() with a different implementation.

Using the Enum

fun main() { val op = Operation.PLUS println("5 + 3 = ${op.apply(5, 3)}") }

Working with Enum Constants

Accessing All Enum Values

Kotlin provides a built-in values() method to access all constants of an enum.

enum class Color { RED, GREEN, BLUE } fun main() { val colors = Color.values() for (color in colors) { println(color) } }

Accessing Enum by Name

Use the valueOf() method to get a constant by its name.

val color = Color.valueOf("RED") println(color) // Output: RED

Enum Properties: name and ordinal

  • name: Returns the name of the enum constant as a String.
  • ordinal: Returns the position of the constant in the declaration, starting from 0.
val color = Color.GREEN println(color.name) // Output: GREEN println(color.ordinal) // Output: 1

Using Enum Classes in When Expressions

Enum classes are particularly useful in when expressions.

fun describe(color: Color): String { return when (color) { Color.RED -> "Color is Red" Color.GREEN -> "Color is Green" Color.BLUE -> "Color is Blue" } }

Sealed Classes vs. Enum Classes

Both sealed classes and enum classes are used to represent restricted hierarchies, but they are different:

Feature Enum Class Sealed Class
Constant values Fixed set of instances Can have subclasses defined anywhere in the same file
Type hierarchy Cannot extend other enums Supports class hierarchy
Inheritance Implicitly inherits from Enum Inherits from Sealed class

Serialization and Enum Classes

When using serialization libraries (e.g., kotlinx.serialization or Gson), enum classes are automatically supported as long as they follow standard conventions.

@Serializable enum class Status { SUCCESS, ERROR, LOADING }

Enum Constants as Anonymous Classes

Each enum constant can be an anonymous class that implements abstract members of the enum class.

enum class Signal { RED { override fun action() = "Stop" }, GREEN { override fun action() = "Go" }, YELLOW { override fun action() = "Wait" }; abstract fun action(): String }

This pattern is useful for polymorphic behavior.

Enum in Data Modeling

Enum classes are great tools for modeling states in finite state machines, fixed status codes, or user roles.

enum class UserRole(val level: Int) { ADMIN(3), MODERATOR(2), USER(1) }

Enums ensure type safety and prevent invalid values being assigned.

Enum Class Limitations

  • Cannot extend other classes (because enum already inherits from Kotlin’s Enum).
  • Cannot be declared as data classes.
  • Cannot be generic.
  • Cannot be nested inside functions.

EnumSet and EnumMap (Using Java Interop)

Kotlin can interoperate with Java, so you can use Java's EnumSet and EnumMap when needed.

val enumSet = EnumSet.of(Color.RED, Color.GREEN) println(enumSet)

These are efficient collections for enums, offering constant-time performance.

Best Practices

  • Use enums for small, well-defined sets of constants.
  • Avoid putting too much logic inside enums. Keep them lightweight.
  • Use properties and methods when enum constants have associated data or behavior.
  • Use when expressions for readable branching logic with enums.
  • Prefer enums over sealed classes for simple constant sets.

Kotlin’s enum classes are a powerful feature that combine simplicity and expressiveness. They allow developers to define a set of constants with their own behavior and data. Enums make your code more readable, safe, and idiomatic. Whether you are modeling directions, user roles, states, or operations, enum classes are a robust choice that integrates well with Kotlin’s language features.

With support for constructors, methods, interfaces, and interoperability with Java, enum classes in Kotlin offer much more than traditional enumerations, making them a key tool in any Kotlin developer’s toolbox.

Related Tutorials

Frequently Asked Questions for Kotlin

Companion objects hold static members, like Java’s static methods, in Kotlin classes.

A concise way to define anonymous functions using { parameters -> body } syntax.

Kotlin prevents null pointer exceptions using nullable (?) and non-null (!!) type syntax.

Inline functions reduce overhead by inserting function code directly at call site.

JetBrains, the makers of IntelliJ IDEA, developed Kotlin and released it in 2011.

Allows non-null variables to be initialized after declaration (used with var only).

val is immutable (read-only), var is mutable (can change value).

Compiler automatically determines variable types, reducing boilerplate code.

A data class automatically provides equals(), hashCode(), toString(), and copy() methods.

A function that takes functions as parameters or returns them.

Kotlin is a modern, statically typed language that runs on the Java Virtual Machine (JVM).

They add new methods to existing classes without modifying their source code.

It allows unpacking data class properties into separate variables.

== checks value equality; === checks reference (memory) equality.


apply is a scope function to configure an object and return it.

A class that restricts subclassing, useful for representing restricted class hierarchies.

Coroutines enable asynchronous programming by suspending and resuming tasks efficiently.

Functions can define default values for parameters, avoiding overloads.

Kotlin offers concise syntax, null safety, and modern features not found in Java.

Kotlin automatically casts variables to appropriate types after type checks.

Use the object keyword to create a singleton.

Calls a method only if the object is non-null.

Yes, Kotlin supports backend development using frameworks like Ktor and Spring Boot.

Data structures like List, Set, and Map, supporting functional operations.

line

Copyrights © 2024 letsupdateskills All rights reserved