Start Coding

Topics

Kotlin Generic Classes

Generic classes in Kotlin provide a powerful way to write flexible and reusable code. They allow you to create classes that can work with different data types while maintaining type safety.

What are Generic Classes?

Generic classes are classes that can operate on objects of various types while providing compile-time type safety. They use type parameters to specify the types of objects they can work with.

Syntax of Generic Classes

To define a generic class in Kotlin, use angle brackets <> after the class name and specify one or more type parameters:

class Box<T>(val item: T) {
    fun getItem(): T {
        return item
    }
}

In this example, T is a type parameter that can represent any type.

Using Generic Classes

To use a generic class, specify the concrete type when creating an instance:

val intBox = Box<Int>(42)
val stringBox = Box<String>("Hello, Generics!")

println(intBox.getItem())    // Output: 42
println(stringBox.getItem()) // Output: Hello, Generics!

Multiple Type Parameters

Generic classes can have multiple type parameters:

class Pair<T, U>(val first: T, val second: U) {
    fun printTypes() {
        println("First type: ${first::class.simpleName}")
        println("Second type: ${second::class.simpleName}")
    }
}

Usage:

val pair = Pair(1, "One")
pair.printTypes()
// Output:
// First type: Int
// Second type: String

Type Constraints

You can apply constraints to type parameters using the : SuperType syntax:

class NumberBox<T : Number>(val value: T) {
    fun square(): Double = value.toDouble() * value.toDouble()
}

This restricts T to be a subtype of Number. For more details on this topic, check out Kotlin Type Constraints.

Benefits of Generic Classes

  • Type safety: Catch type-related errors at compile-time
  • Code reusability: Write classes that work with multiple types
  • Improved readability: Express intentions clearly in the code
  • Reduced code duplication: Avoid writing similar classes for different types

Best Practices

  1. Use meaningful names for type parameters (e.g., T for type, E for element)
  2. Apply type constraints when necessary to ensure type safety
  3. Consider using Kotlin Variance (in, out) for better type flexibility
  4. Combine generics with Kotlin Interfaces for more powerful abstractions

Conclusion

Generic classes in Kotlin offer a robust way to create flexible and type-safe code. By mastering this concept, you can significantly improve your code's reusability and maintainability. For more advanced topics related to generics, explore Kotlin Generic Functions and Kotlin Variance.