androidengineers.Book a session

Programming Fundamentals & Kotlin

Object-Oriented Programming (Classes, Inheritance)

article60 minMedium

Object-oriented programming helps you model real concepts in code. In Android apps, you might model a User, Course, Lesson, Payment, or Notification.

Classes And Objects

A class is a blueprint. An object is a real instance created from that blueprint.

class Course(
    val title: String,
    val lessonCount: Int
) {
    fun description(): String {
        return "$title has $lessonCount lessons"
    }
}

val course = Course("Junior Android Developer", 22)
println(course.description())

Data Classes

Use data class for objects that mainly hold data.

data class Lesson(
    val title: String,
    val durationMinutes: Int,
    val completed: Boolean
)

Kotlin automatically gives data classes useful behavior like copy, equals, and readable toString.

val lesson = Lesson("Kotlin Basics", 30, false)
val completedLesson = lesson.copy(completed = true)

Encapsulation

Encapsulation means keeping internal details private and exposing only what other code needs.

class ProgressTracker {
    private var completed = 0

    fun markDone() {
        completed++
    }

    fun currentProgress(): Int = completed
}

This prevents random parts of your app from changing progress incorrectly.

Inheritance

Inheritance lets one class reuse behavior from another, but use it carefully. Kotlin classes are final by default. You must mark a class open to allow inheritance.

open class Animal {
    open fun speak() = "sound"
}

class Dog : Animal() {
    override fun speak() = "bark"
}

In Android, composition is often preferred over deep inheritance. Instead of making huge base classes, inject dependencies and keep components small.

Interfaces

An interface defines a contract: a list of functions a class must implement.

interface UserRepository {
    suspend fun getUser(id: String): User
    suspend fun saveUser(user: User)
}

A class can then implement that contract:

class RemoteUserRepository(private val api: UserApi) : UserRepository {
    override suspend fun getUser(id: String) = api.fetchUser(id)
    override suspend fun saveUser(user: User) = api.updateUser(user)
}

Interfaces matter in Android because they let you swap implementations. In tests, you swap the real repository for a fake one. In production, you use the real one. The ViewModel never needs to know the difference.

Objects and Companion Objects

An object creates a single instance — a singleton.

object AnalyticsLogger {
    fun log(event: String) {
        println("Event: $event")
    }
}

AnalyticsLogger.log("screen_viewed")

A companion object belongs to a class and is accessed on the class itself, not an instance.

class UserRepository {
    companion object {
        const val MAX_CACHE_SIZE = 100
    }
}

println(UserRepository.MAX_CACHE_SIZE)

You will see companion objects used for constants, factory functions, and log tags.

Practice

Create a Student data class with name, completedLessons, and totalLessons. Add a function that returns whether the student has completed the course.

Summary

Classes model behavior and data. Data classes are perfect for app state and API models. Interfaces define contracts for swappable implementations. Objects and companion objects provide single instances and constants. Inheritance exists, but beginner Android developers should prefer simple composition and clear data models.

YOUR LEARNING JOURNEY

0 of 22 available lessons completed

Progress saved in this browser. No account needed.
Object-Oriented Programming (Classes, Inheritance) | Junior Android Developer | Android Engineers