Sling Academy
Home/Kotlin/Understanding Polymorphism in Kotlin: Compile-Time and Runtime

Understanding Polymorphism in Kotlin: Compile-Time and Runtime

Last updated: November 30, 2024

Polymorphism is a fundamental concept in object-oriented programming that allows objects to be treated as instances of their parent class. In Kotlin, and many other programming languages, it helps in executing a method or property that can be overridden at compile-time and runtime. Let's dive deep into understanding polymorphism in Kotlin with examples.

Compile-Time Polymorphism

Compile-time polymorphism is achieved using method overloading in Kotlin. This means you can have multiple methods with the same name but different signatures (different parameters).


fun add(a: Int, b: Int): Int {
    return a + b
}

fun add(a: Double, b: Double): Double {
    return a + b
}

fun add(a: String, b: String): String {
    return a + b
}

In the above code, we have three overloaded add functions where Kotlin determines which method to execute during the compile-time based on the parameters passed.

Runtime Polymorphism

Runtime polymorphism in Kotlin is achieved using method overriding. This happens when a subclass has a specific implementation of a method that is already defined in its superclass.


open class Animal {
    open fun sound() {
        println("Animal is making a sound")
    }
}

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

fun main(args: Array<String>) {
    val myAnimal: Animal = Dog()
    myAnimal.sound()  // Output: Dog is barking
}

Here, the function sound() is overridden in the Dog class. When sound() is called on an object of class Animal that is actually an instance of Dog, the subclass’s method is executed due to runtime polymorphism.

Polymorphic Methods and Properties

Kotlin allows overriding properties too, preserving the property type safety:


open class Shape {
    open val area: Double
        get() = 0.0
}

class Circle(val radius: Double) : Shape() {
    override val area: Double
        get() = Math.PI * radius * radius
}

fun main() {
    val myCircle: Shape = Circle(2.5)
    println("Area of the circle: ${myCircle.area}")
}

In the Circle class, the area property is overridden from the Shape class, and the overridden property calculates the area of a circle.

Final Thoughts

Understanding polymorphism is crucial for effective software architecture and design. It empowers developers to create flexible and maintainable code. Kotlin’s concise syntax and language features make using polymorphism straightforward and intuitive.

Next Article: How to Use Abstract Classes for Flexible Inheritance in Kotlin

Previous Article: Kotlin: Using the `super` Keyword to Access Parent Class Members

Series: Kotlin Object-Oriented Programming

Kotlin

You May Also Like

  • How to Use Modulo for Cyclic Arithmetic in Kotlin
  • Kotlin: Infinite Loop Detected in Code
  • Fixing Kotlin Error: Index Out of Bounds in List Access
  • Setting Up JDBC in a Kotlin Application
  • Creating a File Explorer App with Kotlin
  • How to Work with APIs in Kotlin
  • What is the `when` Expression in Kotlin?
  • Writing a Script to Rename Multiple Files Programmatically in Kotlin
  • Using Safe Calls (`?.`) to Avoid NullPointerExceptions in Kotlin
  • Chaining Safe Calls for Complex Operations in Kotlin
  • Using the Elvis Operator for Default Values in Kotlin
  • Combining Safe Calls and the Elvis Operator in Kotlin
  • When to Avoid the Null Assertion Operator (`!!`) in Kotlin
  • How to Check for Null Values with `if` Statements in Kotlin
  • Using `let` with Nullable Variables for Scoped Operations in Kotlin
  • Kotlin: How to Handle Nulls in Function Parameters
  • Returning Nullable Values from Functions in Kotlin
  • Safely Accessing Properties of Nullable Objects in Kotlin
  • How to Use `is` for Nullable Type Checking in Kotlin