Understanding ‘12’ Different Types of Kotlin Classes with Real Use Cases and Examples

Sumeet Panchal
4 min read2 days ago

--

Kotlin provides a variety of class types, each serving a specific purpose. Understanding these class types can help developers write more efficient and maintainable code. Let’s explore the different class types in Kotlin, their real-world use cases, and example implementations.

1. Normal Class

A normal class in Kotlin is a basic blueprint for creating objects. It defines properties and methods that describe an entity.

Use Case:

Used for defining reusable components such as Person, Car, or BankAccount. It is the most common class type for object-oriented programming.

class Person(val name: String, val age: Int) {
fun greet() = "Hello, my name is $name and I am $age years old."
}

val person = Person("Sumeet", 30)
println(person.greet())

2. Data Class

A data class is used to hold data and automatically provides implementations for equals(), hashCode(), and toString(). It is optimized for storing and comparing immutable data.

Use Case:

Ideal for representing domain models such as User, Product, or Order, where object equality is based on the content rather than the reference.

data class User(val id: Int, val name: String, val email: String)

val user = User(1, "Sumeet", "sumeet@example.com")
println(user)

3. Object Class

An object class is a singleton, meaning only one instance exists. This is useful for stateful components and utility functions.

Use Case:

Useful for utility classes, configurations, or global state management, ensuring a single instance is shared across the application.

object Logger {
fun log(message: String) = println("LOG: $message")
}

Logger.log("Application started")

4. Data Object Class (Kotlin 1.9+)

A data object is a singleton version of a data class. It combines the benefits of both object and data class, providing a unique identity along with data properties.

Use Case:

It represents unique constant entities, such as predefined system users or configuration settings.

data object AdminUser {
val role = "Administrator"
}

println(AdminUser.role)

5. Enum Class

An enum class represents a fixed set of constants and is often used for representing discrete values.

Use Case:

Used for defining states, modes, or predefined options, such as HTTP status codes, user roles, or payment statuses.

enum class PaymentStatus {
PENDING, COMPLETED, FAILED
}

val status = PaymentStatus.COMPLETED
println(status)

6. Sealed Class

A sealed class restricts class hierarchy to predefined types. It is often used in scenarios where exhaustive type-checking is needed.

Use Case:

Used for representing restricted states in state management, such as API responses that can either be Success or Failure.

sealed class Result {
data class Success(val data: String) : Result()
data class Failure(val error: String) : Result()
}

fun handleResult(result: Result) {
when (result) {
is Result.Success -> println("Success: ${result.data}")
is Result.Failure -> println("Failure: ${result.error}")
}
}

7. Abstract Class

An abstract class cannot be instantiated and must be subclassed. It is used to define common behavior that must be implemented by subclasses.

Use Case:

Used for defining a common template for related classes while enforcing specific functionality in subclasses.

abstract class Vehicle(val name: String) {
abstract fun move()
}

class Car(name: String) : Vehicle(name) {
override fun move() = println("$name is driving")
}

val car = Car("Tesla")
car.move()

8. Open Class

An open class allows inheritance, unlike normal Kotlin classes which are final by default.

Use Case:

Used when a class needs to be extended by other classes to provide additional functionality.

open class Animal(val name: String) {
open fun sound() = "Some sound"
}

class Dog(name: String) : Animal(name) {
override fun sound() = "Bark"
}

val dog = Dog("Buddy")
println(dog.sound())

9. Anonymous Class

An anonymous class is used when an instance of an interface or class is needed without formally declaring a subclass.

Use Case:

Used for quick implementations of interfaces, especially in event handling and callbacks.

interface ClickListener {
fun onClick()
}

val button = object : ClickListener {
override fun onClick() = println("Button clicked!")
}

button.onClick()

10. Value Class (Kotlin 1.5+)

A value class is a lightweight wrapper around a single value, optimizing memory usage.

Use Case:

Used for type safety and optimization, preventing incorrect value assignments.

@JvmInline
value class Email(val value: String)

val email = Email("test@example.com")
println(email.value)

11. Annotation Class

An annotation class is used to define metadata, which can be applied to elements in the code for tooling and reflection.

Use Case:

Used for marking elements for processing by tools or frameworks, such as dependency injection and serialization.

annotation class MyAnnotation

@MyAnnotation
class Example

12. Inner Class

An inner class is a nested class that retains access to the outer class instance, unlike normal nested classes.

Use Case:

Used when a nested class needs to access outer class members to maintain contextual relationships.

class Outer(val outerValue: String) {
inner class Inner {
fun show() = println("Outer value: $outerValue")
}
}

val inner = Outer("Hello").Inner()
inner.show()

Conclusion

Kotlin provides different class types, each catering to specific needs. Using the appropriate class type can enhance code readability, maintainability, and efficiency. Understanding when and how to use these classes will help in building robust Kotlin applications.

Which class type do you use most often in your projects? Let me know in the comments!

--

--

Sumeet Panchal
Sumeet Panchal

Written by Sumeet Panchal

Programming enthusiast specializing in Android and React Native, passionate about crafting intuitive mobile experiences and exploring innovative solutions.

No responses yet