Careeroza
Polymorphism
One Type, Many Forms
A variable of a parent type can hold any child object. When you call an overridden function, Kotlin runs the version of the actual object at runtime (dynamic dispatch). This lets you write code once for all subtypes.
Example
open class Notification(val to: String) {
open fun send() = println("Sending notification to $to")
}
class SmsNotification(to: String) : Notification(to) {
override fun send() = println("SMS to $to: Your OTP is 4821")
}
class EmailNotification(to: String) : Notification(to) {
override fun send() = println("Email to $to: Order confirmed")
}
class PushNotification(to: String) : Notification(to) {
override fun send() = println("Push to $to: Your food is on the way")
}
fun notifyAll(list: List<Notification>) {
for (n in list) n.send() // the right version is picked at runtime
}
fun main() {
notifyAll(listOf(
SmsNotification("+91 98xxxx1234"),
EmailNotification("[email protected]"),
PushNotification("device-77"),
))
}Output
SMS to +91 98xxxx1234: Your OTP is 4821 Email to [email protected]: Order confirmed Push to device-77: Your food is on the way
Overloading vs Overriding
| Overloading | Overriding | |
|---|---|---|
| What | same name, different parameters | same signature in a subclass |
| Decided at | compile time | runtime |
| Keyword | none | override (parent must be open) |
| Example | sum(a, b) and sum(a, b, c) | send() in SmsNotification |
Exercise
Exercise: Create an open class Vehicle with an open function fare(km: Int): Int returning km * 10. Override it in Auto (km * 15) and Bike (km * 7). Print the fare for 5 km for each vehicle in a list.
Show answer
open class Vehicle { open fun fare(km: Int) = km * 10 }
class Auto : Vehicle() { override fun fare(km: Int) = km * 15 }
class Bike : Vehicle() { override fun fare(km: Int) = km * 7 }
fun main() {
listOf(Vehicle(), Auto(), Bike()).forEach { println(it.fare(5)) } // 50, 75, 35
}