All days
Day 03Module 2 · OOP in Kotlin· 3–5 hrs

OOP I — Classes, Constructors, Inheritance, Polymorphism

Object-oriented programming Kotlin-style: concise classes, primary and secondary constructors, custom getters/setters, and inheritance with overriding.

0% done

Key concepts

  • class and data class
  • Primary constructor (in class header)
  • Secondary constructors
  • Custom get() / set()
  • open class / open fun — inheritance is opt-in
  • override and super
  • Runtime polymorphism

Lectures in this day

  1. 01

    Class and Object Definitions

    A class is a blueprint that says what a thing has (properties) and what it can do (functions). An object is an actual thing made from that blueprint. A `data class` is a shortcut for classes that mostly just hold data — Kotlin writes the boring bits for you.

    Real life · One blueprint of a house (the class) can be used to build many real houses (the objects).
    kotlin
    0
    data class Book(val title: String, val author: String, val pages: Int)
    
    1
    val b = Book("Deep Work", "Cal Newport", 296)
    println(b)                          2
    
    3
    val short = b.copy(pages = 120)
    println(short)

    Practice · 3 quick questions

    1. Q1.A class is best described as…

    2. Q2.An object is…

    3. Q3.You create an object with…

    Pick one answer per question.
  2. 02

    Various Constructors and Custom Getter/Setter

    A constructor is the recipe for making a new object. The main one is written in the class header. You can add extra recipes with `constructor(...)`. A property can also run a small piece of code every time you read it (getter) or write to it (setter).

    Real life · Sign-up forms: one long form asks for everything (main), a short form uses defaults for the rest (extra). A setter that trims spaces is like a form that tidies your typing automatically.
    kotlin
    class User(firstName: String, val lastName: String) {
    
        0
        var firstName: String = firstName
            set(value) {
                field = value.trim()   1
            }
    
        2
        val fullName: String
            get() = "$firstName $lastName"
    
        3
        constructor(only: String) : this(only, "—")
    }
    
    val u = User("  Rakib  ", "Hasan")
    println(u.fullName)   4

    Practice · 3 quick questions

    1. Q1.A primary constructor sits…

    2. Q2.A custom setter lets you…

    3. Q3.Inside a setter, `field` means…

    Pick one answer per question.
  3. 03

    Inheritance and Method Overriding

    Inheritance means one class can build on another. The child class gets everything the parent has, and can add or change parts. In Kotlin you must mark a class or function `open` before it can be extended or changed. `override` means 'I am replacing the parent's version'.

    Real life · Every worker in a company has a name and can write a report. A Manager is still a worker, but their report also includes the team's progress.
    kotlin
    open class Employee(val name: String) {           0
        open fun dailyReport() = "$name: worked 8 hours" 1
    }
    
    class Manager(name: String) : Employee(name) {
        override fun dailyReport() =                     2
            "${super.dailyReport()} + reviewed team"    3
    }
    
    println(Manager("Rima").dailyReport())

    Practice · 3 quick questions

    1. Q1.To allow a class to be inherited, mark it…

    2. Q2.To replace a parent's method, use…

    3. Q3.Which keyword refers to the parent?

    Pick one answer per question.
  4. 04

    Runtime Polymorphism

    Polymorphism means 'many shapes'. The SAME line of code can behave differently depending on the actual object it runs on. Kotlin picks the right version at run time.

    Real life · One 'Play' button on a universal remote: on the TV it plays a show, on the speaker it plays music. Same button, different behavior.
    kotlin
    open class Shape {
        open fun area(): Double = 0.0
    }
    class Circle(val r: Double) : Shape() {
        override fun area() = Math.PI * r * r
    }
    class Square(val s: Double) : Shape() {
        override fun area() = s * s
    }
    
    0
    val shapes: List<Shape> = listOf(Circle(2.0), Square(3.0))
    shapes.forEach { println(it.area()) }
    1

    Practice · 3 quick questions

    1. Q1.Runtime polymorphism means…

    2. Q2.It requires…

    3. Q3.Which is a benefit?

    Pick one answer per question.

Real-life analogies

open keyword

In Java, everything's unlocked by default. In Kotlin, classes are locked (final) — you `open` them like unlocking a door before someone can extend them.

Polymorphism

A universal remote: press 'Play' and the TV plays a show, the speaker plays music. Same button, different behavior depending on the device.

Code examples

Class hierarchy

kotlin
open class Vehicle(val brand: String, val wheels: Int) {
    open fun describe() = "$brand vehicle with $wheels wheels"
}

class Car(brand: String) : Vehicle(brand, 4) {
    override fun describe() = "${super.describe()} — a car"
}

class Bike(brand: String) : Vehicle(brand, 2) {
    override fun describe() = "${super.describe()} — a bike"
}

val fleet: List<Vehicle> = listOf(Car("Toyota"), Bike("Yamaha"))
fleet.forEach { println(it.describe()) } 0

Custom getter/setter

kotlin
class User(firstName: String, lastName: String) {
    var firstName: String = firstName
        set(value) { field = value.trim() }

    val fullName: String
        get() = "$firstName $lastName"

    val lastName: String = lastName
}

`field` is the backing storage — you can't self-assign the property or you get infinite recursion.

Hands-on checklist

Milestone

A class hierarchy with 3+ classes showing inheritance & overriding.

Common pitfalls

  • Forgetting `open` on the parent class — child won't compile.
  • Using `this.name = value` in a custom setter instead of `field = value` — infinite recursion.