Static vs Runtime Polymorphism in Kotlin

Polymorphism in Kotlin can be classified into two main types based on when the method to be executed is determined: static (compile-time) polymorphism and runtime (dynamic) polymorphism.

1. Why Understanding the Difference Matters

2. Static (Compile-time) Polymorphism

Static polymorphism is resolved during compilation. The compiler determines which method to call based on the method signature, i.e., the number or types of parameters. This is typically achieved through method overloading.

2.1 Example: Method Overloading


class Calculator {
    fun add(a: Int, b: Int) = a + b
    fun add(a: Int, b: Int, c: Int) = a + b + c
}

fun main() {
val calc = Calculator()
println(calc.add(2, 3))       // Output: 5
println(calc.add(2, 3, 4))    // Output: 9
} 

Explanation: The compiler decides which add method to call based on the number of arguments provided. This is resolved at compile time.

3. Runtime (Dynamic) Polymorphism

Runtime polymorphism is resolved during program execution. It occurs when a subclass provides its own implementation of a method defined in a parent class or interface. This is achieved through method overriding and interface implementation.

3.1 Example: Method Overriding


open class Animal {
    open fun sound() {
        println("Some generic sound")
    }
}

class Dog : Animal() {
override fun sound() {
println("Bark")
}
}

fun main() {
val animal: Animal = Dog()  // Reference of type Animal, object is Dog
animal.sound()              // Output determined at runtime: Bark
} 

Explanation: Although the reference type is Animal, the actual object is Dog. The JVM decides at runtime to call Dog's sound() method.

4. Key Differences: Static vs Runtime Polymorphism

Aspect Static (Compile-time) Polymorphism Runtime (Dynamic) Polymorphism
Resolution At compile time At runtime
Achieved By Method overloading Method overriding, interface implementation
Performance Faster, no runtime overhead Slower, runtime dispatch needed
Flexibility Less flexible, fixed at compile time Highly flexible, dynamic behavior
Use Case Multiple methods with different parameters Polymorphic behavior for different object types

5. Technical Interview Questions

6. Key Takeaways