Careeroza
Real World Example
Ride Types in a Ride-hailing App
Uber, Ola and Rapido offer several ride types that share most logic (base fare, distance) but differ in pricing rules. A parent class holds the common code and each ride type overrides only what changes.
Example
open class Ride(val distanceKm: Double) {
open val name = "Ride"
open val baseFare = 30.0
open val perKm = 10.0
open fun fare(): Double = baseFare + distanceKm * perKm
fun receipt() = println("%-8s %5.1f km Rs %.0f".format(name, distanceKm, fare()))
}
class BikeRide(d: Double) : Ride(d) {
override val name = "Bike"
override val baseFare = 15.0
override val perKm = 6.0
}
class AutoRide(d: Double) : Ride(d) {
override val name = "Auto"
override val perKm = 12.0
}
class PremiumRide(d: Double, val surge: Double) : Ride(d) {
override val name = "Premier"
override val baseFare = 80.0
override val perKm = 18.0
override fun fare() = super.fare() * surge // reuse parent logic
}
fun main() {
val options = listOf(BikeRide(8.0), AutoRide(8.0), Ride(8.0), PremiumRide(8.0, 1.25))
options.forEach { it.receipt() }
}Output
Bike 8.0 km Rs 63 Auto 8.0 km Rs 126 Ride 8.0 km Rs 110 Premier 8.0 km Rs 280
Android: a Base Activity
Many Android projects have a base class with shared behaviour (analytics, loading dialog). Every screen extends it and calls super in lifecycle methods.
abstract class BaseActivity : AppCompatActivity() {
abstract val screenName: String
override fun onResume() {
super.onResume() // always call the framework version
Analytics.logScreen(screenName)
}
protected fun showError(message: String) {
Snackbar.make(findViewById(android.R.id.content), message, Snackbar.LENGTH_LONG).show()
}
}
class CheckoutActivity : BaseActivity() {
override val screenName = "checkout"
}Tip: Prefer composition over deep inheritance trees. One or two levels is fine; five levels of base classes become hard to change.