Kotlin Abstract Class

A Kotlin abstract class is a special type of class that cannot be instantiated directly and serves as a blueprint for other classes. The abstract keyword in Kotlin is used to declare these classes, which can contain both abstract and concrete members. Unlike regular classes, Kotlin abstract classes are designed to be inherited by subclasses that must implement all abstract methods and properties defined in the parent abstract class.

The primary purpose of Kotlin abstract class is to provide a common template that multiple related classes can extend while enforcing certain methods to be implemented by child classes. This makes Kotlin abstract classes essential for creating well-structured, inheritance-based architectures in Android applications.

Kotlin Abstract Class Syntax and Declaration

To declare a Kotlin abstract class, you use the abstract keyword before the class definition. Here’s the basic syntax for Kotlin abstract class declaration:

abstract class AbstractClassName {  
    // Abstract properties  
    abstract var abstractProperty: String  
      
    // Abstract methods  
    abstract fun abstractMethod(): Unit  
      
    // Concrete properties  
    var concreteProperty: String = "Default Value"  
      
    // Concrete methods  
    fun concreteMethod() {  
        println("This is a concrete method")  
    }  
}  

Key Properties of Kotlin Abstract Class:

1. Cannot Be Instantiated: You cannot create objects directly from a Kotlin abstract class. This is the fundamental characteristic that distinguishes abstract classes from regular classes.

abstract class Vehicle {  
    abstract fun start()  
}  
  
// This will cause a compilation error  
// val vehicle = Vehicle() // Error: Cannot create an instance of an abstract class  

2. Can Contain Abstract Members: Kotlin abstract classes can have abstract properties and methods that must be implemented by subclasses.

abstract class Shape {  
    abstract val area: Double  
    abstract fun calculatePerimeter(): Double  
}  

3. Can Contain Concrete Members: Unlike interfaces, Kotlin abstract classes can have concrete implementations alongside abstract ones.

abstract class Animal {  
    // Concrete property  
    var species: String = "Unknown"  
      
    // Concrete method  
    fun eat() {  
        println("Animal is eating")  
    }  
      
    // Abstract method  
    abstract fun makeSound()  
}  

4. Always Open for Inheritance: Kotlin abstract classes are implicitly open, meaning you don’t need to use the open keyword for inheritance.

abstract class BaseClass {  
    abstract fun abstractFunction()  
}  
  
// No need for 'open' keyword  
class ChildClass : BaseClass() {  
    override fun abstractFunction() {  
        println("Implementation in child class")  
    }  
}  

Kotlin Abstract Methods and Properties

Abstract Methods in Kotlin

Kotlin abstract methods are function declarations without implementation that must be overridden in subclasses. Here’s how to define and use abstract methods in Kotlin:

abstract class Database {  
    // Abstract method without implementation  
    abstract fun connect(url: String): Boolean  
      
    // Abstract method with parameters  
    abstract fun executeQuery(query: String): List<String>  
      
    // Concrete method that can use abstract methods  
    fun performOperation(query: String) {  
        if (connect("database://localhost")) {  
            val results = executeQuery(query)  
            println("Operation completed with ${results.size} results")  
        }  
    }  
}  

Abstract Properties in Kotlin

Kotlin abstract properties define property declarations that subclasses must implement:

abstract class Configuration {  
    // Abstract val property  
    abstract val serverUrl: String  
      
    // Abstract var property  
    abstract var timeout: Int  
      
    // Concrete property  
    val version: String = "1.0"  
      
    // Method using abstract properties  
    fun displayConfig() {  
        println("Server: $serverUrl, Timeout: $timeout, Version: $version")  
    }  
}  

Implementing Kotlin Abstract Class

When you inherit from a Kotlin abstract class, you must implement all abstract members. Here’s a comprehensive example showing Kotlin abstract class implementation:

abstract class MediaPlayer {  
    // Abstract properties  
    abstract val supportedFormats: List<String>  
    abstract var currentVolume: Int  
      
    // Abstract methods  
    abstract fun play(file: String): Boolean  
    abstract fun pause(): Boolean  
    abstract fun stop(): Boolean  
      
    // Concrete properties  
    var isPlaying: Boolean = false  
      
    // Concrete methods  
    fun getStatus(): String {  
        return if (isPlaying) "Playing" else "Stopped"  
    }  
      
    protected fun validateFormat(file: String): Boolean {  
        val extension = file.substringAfterLast(".")  
        return supportedFormats.contains(extension)  
    }  
}  
  
class AudioPlayer : MediaPlayer() {  
    // Implementing abstract properties  
    override val supportedFormats = listOf("mp3", "wav", "flac")  
    override var currentVolume = 50  
      
    // Implementing abstract methods  
    override fun play(file: String): Boolean {  
        if (!validateFormat(file)) {  
            println("Unsupported audio format")  
            return false  
        }  
          
        isPlaying = true  
        println("Playing audio file: $file at volume $currentVolume")  
        return true  
    }  
      
    override fun pause(): Boolean {  
        if (isPlaying) {  
            isPlaying = false  
            println("Audio paused")  
            return true  
        }  
        return false  
    }  
      
    override fun stop(): Boolean {  
        isPlaying = false  
        currentVolume = 0  
        println("Audio stopped")  
        return true  
    }  
      
    // Additional concrete method specific to AudioPlayer  
    fun adjustBass(level: Int) {  
        println("Bass adjusted to level: $level")  
    }  
}  

Kotlin Abstract Class with Constructor

Kotlin abstract classes can have constructors, including primary and secondary constructors:

abstract class Employee(  
    val name: String,  
    val id: Int  
) {  
    // Secondary constructor  
    constructor(name: String, id: Int, department: String) : this(name, id) {  
        this.department = department  
    }  
      
    var department: String = "General"  
      
    // Abstract method  
    abstract fun calculateSalary(): Double  
      
    // Concrete method  
    fun getEmployeeInfo(): String {  
        return "Employee: $name (ID: $id) - Department: $department"  
    }  
}  
  
class Developer(  
    name: String,  
    id: Int,  
    private val experience: Int  
) : Employee(name, id, "Engineering") {  
      
    override fun calculateSalary(): Double {  
        return 50000.0 + (experience * 5000.0)  
    }  
      
    fun writeCode(language: String) {  
        println("$name is writing code in $language")  
    }  
}  
  
class Manager(  
    name: String,  
    id: Int,  
    private val teamSize: Int  
) : Employee(name, id, "Management") {  
      
    override fun calculateSalary(): Double {  
        return 70000.0 + (teamSize * 2000.0)  
    }  
      
    fun conductMeeting() {  
        println("$name is conducting a team meeting")  
    }  
}  

Kotlin Abstract Class vs Interface

Understanding the differences between Kotlin abstract class and interface is crucial for making the right design decisions:

FeatureKotlin Abstract ClassKotlin Interface
InstantiationCannot be instantiatedCannot be instantiated
State StorageCan store state (properties with values)Cannot store state (properties must be abstract or have custom accessors)
ConstructorCan have constructorsCannot have constructors
InheritanceSingle inheritance onlyMultiple interface implementation
Abstract MembersCan have abstract and concrete membersAll members are abstract by default (except with default implementations)
// Abstract class example  
abstract class AbstractVehicle {  
    var fuel: Double = 0.0  // Can store state  
    abstract fun startEngine()  
}  
  
// Interface example  
interface VehicleInterface {  
    // val fuel: Double = 0.0  // Error: Cannot store state  
    val fuel: Double  // Must be abstract  
    fun startEngine()  
}  

Advanced Kotlin Abstract Class Examples

Nested Abstract Classes

Kotlin abstract classes can contain nested abstract classes:

abstract class GameEngine {  
    abstract fun render()  
      
    abstract class Renderer {  
        abstract fun drawSprite(x: Int, y: Int)  
        abstract fun drawText(text: String, x: Int, y: Int)  
          
        fun clearScreen() {  
            println("Screen cleared")  
        }  
    }  
      
    abstract class AudioSystem {  
        abstract fun playSound(soundId: String)  
        abstract fun stopAllSounds()  
    }  
}  
  
class Unity3DEngine : GameEngine() {  
    override fun render() {  
        println("Unity3D rendering frame")  
    }  
      
    class UnityRenderer : Renderer() {  
        override fun drawSprite(x: Int, y: Int) {  
            println("Drawing Unity sprite at ($x, $y)")  
        }  
          
        override fun drawText(text: String, x: Int, y: Int) {  
            println("Drawing Unity text '$text' at ($x, $y)")  
        }  
    }  
}  

Abstract Class with Generic Types

Kotlin abstract classes support generic parameters:

abstract class Repository<T> {  
    abstract fun save(item: T): Boolean  
    abstract fun findById(id: String): T?  
    abstract fun findAll(): List<T>  
    abstract fun delete(id: String): Boolean  
      
    protected fun validateItem(item: T): Boolean {  
        return item != null  
    }  
      
    fun count(): Int {  
        return findAll().size  
    }  
}  
  
class UserRepository : Repository<User>() {  
    private val users = mutableMapOf<String, User>()  
      
    override fun save(item: User): Boolean {  
        if (!validateItem(item)) return false  
        users[item.id] = item  
        return true  
    }  
      
    override fun findById(id: String): User? {  
        return users[id]  
    }  
      
    override fun findAll(): List<User> {  
        return users.values.toList()  
    }  
      
    override fun delete(id: String): Boolean {  
        return users.remove(id) != null  
    }  
}  
  
data class User(val id: String, val name: String, val email: String)  

Complete Working Example: E-commerce System

Here’s a comprehensive example demonstrating Kotlin abstract class usage in an e-commerce context:

// Import statements (if needed)  
import kotlin.math.PI  
  
// Abstract base class for products  
abstract class Product(  
    val id: String,  
    val name: String,  
    protected var basePrice: Double  
) {  
    // Abstract properties  
    abstract val category: String  
    abstract val weight: Double  
      
    // Abstract methods  
    abstract fun calculatePrice(): Double  
    abstract fun getShippingCost(): Double  
      
    // Concrete properties  
    var isAvailable: Boolean = true  
    var description: String = ""  
      
    // Concrete methods  
    fun displayInfo() {  
        println("Product: $name")  
        println("Category: $category")  
        println("Price: $${calculatePrice()}")  
        println("Shipping: $${getShippingCost()}")  
        println("Available: $isAvailable")  
        if (description.isNotEmpty()) {  
            println("Description: $description")  
        }  
        println("---")  
    }  
      
    protected fun applyTax(amount: Double): Double {  
        return amount * 1.08 // 8% tax  
    }  
}  
  
// Electronics product implementation  
class Electronics(  
    id: String,  
    name: String,  
    basePrice: Double,  
    private val warrantyMonths: Int,  
    override val weight: Double  
) : Product(id, name, basePrice) {  
      
    override val category = "Electronics"  
      
    override fun calculatePrice(): Double {  
        val warrantyFee = warrantyMonths * 10.0  
        return applyTax(basePrice + warrantyFee)  
    }  
      
    override fun getShippingCost(): Double {  
        return when {  
            weight <= 1.0 -> 5.99  
            weight <= 5.0 -> 12.99  
            else -> 25.99  
        }  
    }  
      
    fun getWarrantyInfo(): String {  
        return "$warrantyMonths months warranty included"  
    }  
}  
  
// Clothing product implementation  
class Clothing(  
    id: String,  
    name: String,  
    basePrice: Double,  
    private val size: String,  
    override val weight: Double  
) : Product(id, name, basePrice) {  
      
    override val category = "Clothing"  
      
    override fun calculatePrice(): Double {  
        val sizePremium = if (size in listOf("XL", "XXL")) 5.0 else 0.0  
        return applyTax(basePrice + sizePremium)  
    }  
      
    override fun getShippingCost(): Double {  
        return if (weight <= 0.5) 3.99 else 7.99  
    }  
      
    fun getSizeInfo(): String {  
        return "Available in size: $size"  
    }  
}  
  
// Books product implementation  
class Book(  
    id: String,  
    name: String,  
    basePrice: Double,  
    private val pageCount: Int,  
    private val isHardcover: Boolean,  
    override val weight: Double  
) : Product(id, name, basePrice) {  
      
    override val category = "Books"  
      
    override fun calculatePrice(): Double {  
        val hardcoverFee = if (isHardcover) 5.0 else 0.0  
        return applyTax(basePrice + hardcoverFee)  
    }  
      
    override fun getShippingCost(): Double {  
        return when {  
            weight <= 0.3 -> 2.99  
            weight <= 1.0 -> 4.99  
            else -> 8.99  
        }  
    }  
      
    fun getBookDetails(): String {  
        val coverType = if (isHardcover) "Hardcover" else "Paperback"  
        return "$coverType, $pageCount pages"  
    }  
}  
  
// Shopping cart to manage products  
class ShoppingCart {  
    private val products = mutableListOf<Product>()  
      
    fun addProduct(product: Product) {  
        products.add(product)  
        println("Added ${product.name} to cart")  
    }  
      
    fun removeProduct(productId: String) {  
        products.removeIf { it.id == productId }  
        println("Removed product with ID: $productId from cart")  
    }  
      
    fun calculateTotal(): Double {  
        return products.sumOf { it.calculatePrice() + it.getShippingCost() }  
    }  
      
    fun displayCart() {  
        if (products.isEmpty()) {  
            println("Cart is empty")  
            return  
        }  
          
        println("=== Shopping Cart ===")  
        products.forEach { it.displayInfo() }  
        println("Total: $${String.format("%.2f", calculateTotal())}")  
        println("=====================")  
    }  
      
    fun getProductCount(): Int = products.size  
}  
  
// Main function demonstrating the usage  
fun main() {  
    // Create various products  
    val laptop = Electronics(  
        id = "E001",  
        name = "Gaming Laptop",  
        basePrice = 1299.99,  
        warrantyMonths = 24,  
        weight = 2.5  
    ).apply {  
        description = "High-performance laptop for gaming and professional work"  
    }  
      
    val tshirt = Clothing(  
        id = "C001",  
        name = "Cotton T-Shirt",  
        basePrice = 29.99,  
        size = "L",  
        weight = 0.3  
    ).apply {  
        description = "100% organic cotton, comfortable fit"  
    }  
      
    val novel = Book(  
        id = "B001",  
        name = "Kotlin Programming Guide",  
        basePrice = 45.99,  
        pageCount = 520,  
        isHardcover = true,  
        weight = 0.8  
    ).apply {  
        description = "Comprehensive guide to Kotlin programming"  
    }  
      
    val smartphone = Electronics(  
        id = "E002",  
        name = "Flagship Smartphone",  
        basePrice = 899.99,  
        warrantyMonths = 12,  
        weight = 0.2  
    ).apply {  
        description = "Latest flagship smartphone with advanced features"  
    }  
      
    // Create shopping cart and add products  
    val cart = ShoppingCart()  
      
    // Add products to cart  
    cart.addProduct(laptop)  
    cart.addProduct(tshirt)  
    cart.addProduct(novel)  
    cart.addProduct(smartphone)  
      
    println("\n")  
      
    // Display cart contents  
    cart.displayCart()  
      
    // Demonstrate specific product methods  
    println("\n=== Product Specific Information ===")  
    println("Laptop warranty: ${laptop.getWarrantyInfo()}")  
    println("T-shirt size: ${tshirt.getSizeInfo()}")  
    println("Book details: ${novel.getBookDetails()}")  
    println("Smartphone warranty: ${smartphone.getWarrantyInfo()}")  
      
    // Remove a product  
    println("\n")  
    cart.removeProduct("C001")  
      
    println("\n")  
    cart.displayCart()  
}  

Expected Output:

Added Gaming Laptop to cart  
Added Cotton T-Shirt to cart  
Added Kotlin Programming Guide to cart  
Added Flagship Smartphone to cart  
  
  
=== Shopping Cart ===  
Product: Gaming Laptop  
Category: Electronics  
Price: $1463.99  
Shipping: $25.99  
Available: true  
Description: High-performance laptop for gaming and professional work  
---  
Product: Cotton T-Shirt  
Category: Clothing  
Price: $32.39  
Shipping: $3.99  
Available: true  
Description: 100% organic cotton, comfortable fit  
---  
Product: Kotlin Programming Guide  
Category: Books  
Price: $55.07  
Shipping: $4.99  
Available: true  
Description: Comprehensive guide to Kotlin programming  
---  
Product: Flagship Smartphone  
Category: Electronics  
Price: $1031.99  
Shipping: $5.99  
Available: true  
Description: Latest flagship smartphone with advanced features  
---  
Total: $2624.39  
=====================  
  
=== Product Specific Information ===  
Laptop warranty: 24 months warranty included  
T-shirt size: Available in size: L  
Book details: Hardcover, 520 pages  
Smartphone warranty: 12 months warranty included  
  
Removed product with ID: C001 from cart  
  
=== Shopping Cart ===  
Product: Gaming Laptop  
Category: Electronics  
Price: $1463.99  
Shipping: $25.99  
Available: true  
Description: High-performance laptop for gaming and professional work  
---  
Product: Kotlin Programming Guide  
Category: Books  
Price: $55.07  
Shipping: $4.99  
Available: true  
Description: Comprehensive guide to Kotlin programming  
---  
Product: Flagship Smartphone  
Category: Electronics  
Price: $1031.99  
Shipping: $5.99  
Available: true  
Description: Latest flagship smartphone with advanced features  
---  
Total: $2588.03  
=====================  

This comprehensive example demonstrates how Kotlin abstract classes provide a solid foundation for building complex, inheritance-based systems. The abstract Product class defines the common structure and behavior that all products must have, while concrete implementations like Electronics, Clothing, and Book provide specific implementations for their respective categories.