Ответ
Полиморфизм времени компиляции (статический) реализуется через перегрузку методов и операторов. Вызываемый метод определяется на этапе компиляции на основе сигнатуры.
Пример перегрузки:
fun sum(a: Int, b: Int) = a + b
fun sum(a: Double, b: Double) = a + b
Полиморфизм времени выполнения (динамический) достигается через переопределение методов при наследовании. Конкретная реализация метода выбирается в runtime на основе типа объекта.
Пример переопределения:
open class Animal {
open fun sound() = "Generic sound"
}
class Dog : Animal() {
override fun sound() = "Bark"
}
val animal: Animal = Dog()
animal.sound() // Вызовется Dog.sound() в runtime