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.00

Abstract 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

Leave a Comment

Your email address will not be published. Required fields are marked *