Kotlin Abstract Classes
An abstract class is a class that cannot be instantiated directly. It exists to be a base for other classes. It can define abstract functions (declared but not implemented) that subclasses must implement, along with regular functions with implementations.
Abstract Class Syntax
abstract class Shape {
abstract fun area(): Double // no body — subclasses must implement
abstract fun perimeter(): Double // no body — subclasses must implement
fun describe() { // regular function with body
println("Area: ${"%.2f".format(area())}, Perimeter: ${"%.2f".format(perimeter())}")
}
}
class Circle(val radius: Double) : Shape() {
override fun area() = Math.PI * radius * radius
override fun perimeter() = 2 * Math.PI * radius
}
class Rectangle(val width: Double, val height: Double) : Shape() {
override fun area() = width * height
override fun perimeter() = 2 * (width + height)
}
fun main() {
val shapes: List = listOf(Circle(5.0), Rectangle(4.0, 6.0))
shapes.forEach { it.describe() }
} Output:
Area: 78.54, Perimeter: 31.42
Area: 24.00, Perimeter: 20.00Abstract vs Open
┌─────────────────────────────────────────────────────────┐
│ Abstract Class Open Class │
├──────────────────────────────────────────────────────── │
│ Can have abstract methods Cannot have abstract │
│ (body required in subclass) methods │
│ │
│ Cannot be instantiated directly CAN be instantiated │
│ (no val a = AbstractClass()) directly │
│ │
│ Subclasses MUST implement Subclasses CAN override│
│ abstract methods open methods │
└─────────────────────────────────────────────────────────┘
Abstract Properties
abstract class Document {
abstract val title: String // subclass must provide this
abstract val wordCount: Int
val summary: String
get() = "'$title' has $wordCount words"
}
class Article(override val title: String, val content: String) : Document() {
override val wordCount: Int
get() = content.split(" ").size
}
fun main() {
val a = Article("Kotlin Tips", "Kotlin is fast concise and safe")
println(a.summary)
// 'Kotlin Tips' has 6 words
}Abstract Class Diagram
«abstract»
Employee
────────────────────
name: String
department: String
abstract salary(): Double
annualCost(): Double = salary() * 12
│
┌────┴──────────┐
│ │
FullTimeEmployee ContractEmployee
salary() = 80000 salary() = hours * rate
(fixed monthly) (per hour)
abstract class Employee(val name: String) {
abstract fun salary(): Double
fun annualCost(): Double = salary() * 12
fun describe() = "$name | Monthly: ₹${salary()} | Annual: ₹${annualCost()}"
}
class FullTimeEmployee(name: String, private val monthlySalary: Double) : Employee(name) {
override fun salary() = monthlySalary
}
class ContractEmployee(name: String, val hoursPerMonth: Int, val ratePerHour: Double) : Employee(name) {
override fun salary() = hoursPerMonth * ratePerHour
}
fun main() {
val team = listOf(
FullTimeEmployee("Alice", 75000.0),
ContractEmployee("Bob", 120, 500.0),
FullTimeEmployee("Carol", 90000.0)
)
team.forEach { println(it.describe()) }
println("Total annual cost: ₹${team.sumOf { it.annualCost() }}")
}Output:
Alice | Monthly: ₹75000.0 | Annual: ₹900000.0
Bob | Monthly: ₹60000.0 | Annual: ₹720000.0
Carol | Monthly: ₹90000.0 | Annual: ₹1080000.0
Total annual cost: ₹2700000.0