Kotlin Delegation Tutorial: Class Delegation, Property Delegation with Mini Projects


This Kotlin Delegation tutorial explains how delegation works in Kotlin, covering class delegation and property delegation. It demonstrates how delegation helps reduce boilerplate code and promotes composition over inheritance. The chapter also includes real-world mini projects such as a file-based student management system and a log file analyzer to apply delegation concepts practically.

Kotlin Delegation – Complete Tutorial

What Is Delegation?

Delegation is a design pattern where an object handles a request by delegating it to another object. Kotlin provides native language support for delegation using the by keyword.

Delegation promotes composition over inheritance, making code more flexible and maintainable.

Class Delegation

Class delegation allows one class to delegate the implementation of an interface to another object.

Without Delegation (Traditional Way)


interface Printer {
fun print()
}

class InkPrinter : Printer {
override fun print() {
println("Printing with ink printer")
}
}

class PrinterManager(private val printer: Printer) : Printer {
override fun print() {
printer.print()
}
}

With Class Delegation (Recommended)


class PrinterManager(printer: Printer) : Printer by printer

Example Usage


fun main() {
val printer = InkPrinter()
val manager = PrinterManager(printer)
manager.print()
}

Best Practices for Class Delegation

  1. Prefer delegation over inheritance.
  2. Delegate behavior, not state.
  3. Keep delegated interfaces small and focused.

Property Delegation

Property delegation allows the logic of getter and setter to be handled by another object.

Kotlin provides built-in delegates like lazy, observable, and vetoable.

lazy Delegation


val message: String by lazy {
println("Initialized")
"Hello Kotlin"
}

fun main() {
println(message)
println(message)
}

observable Delegation


import kotlin.properties.Delegates

var userName: String by Delegates.observable("Guest") { _, old, new ->
println("Name changed from $old to $new")
}

fun main() {
userName = "Muni"
}

Custom Property Delegation


import kotlin.reflect.KProperty

class LoggerDelegate {
operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
return "Accessing ${property.name}"
}
}

class AppConfig {
val config: String by LoggerDelegate()
}

fun main() {
val app = AppConfig()
println(app.config)
}

Best Practices for Property Delegation

  1. Use lazy for expensive initialization.
  2. Use observable for tracking state changes.
  3. Create custom delegates for reusable property logic.

Mini Projects

Mini Project 1: File-Based Student Management System

Features

  1. Add student records
  2. Save to file
  3. Read from file

Code Example


import java.io.File

data class Student(val id: Int, val name: String, val marks: Int)

class StudentRepository(private val file: File) {

fun addStudent(student: Student) {
file.appendText("${student.id},${student.name},${student.marks}\n")
}

fun readStudents(): List<Student> {
if (!file.exists()) return emptyList()

return file.readLines().map {
val parts = it.split(",")
Student(parts[0].toInt(), parts[1], parts[2].toInt())
}
}
}

fun main() {
val repo = StudentRepository(File("students.txt"))
repo.addStudent(Student(1, "Muni", 85))
println(repo.readStudents())
}

Concepts Used

  1. Data classes
  2. File handling
  3. Clean separation of responsibility

Mini Project 2: Log File Analyzer

Features

  1. Read log file
  2. Count error entries
  3. Display summary

Code Example


import java.io.File

fun main() {
val logFile = File("app.log")

if (!logFile.exists()) {
println("Log file not found")
return
}

val errorCount = logFile.readLines()
.count { it.contains("ERROR") }

println("Total ERROR entries: $errorCount")
}

Enhancements (Practice)

  1. Add delegation for logging configuration
  2. Filter logs by date or level
  3. Export summary report

Summary

This chapter covered Kotlin delegation in depth, including class delegation and property delegation using built-in and custom delegates. Delegation helps reduce boilerplate code and improves design flexibility. The included mini projects demonstrated practical usage of delegation, file handling, and functional programming concepts.