Skip to main content
Kotlin Basics
CHAPTER 16 Beginner

Interfaces and Abstract Classes

Updated: May 18, 2026
5 min read

# CHAPTER 16

Interfaces and Abstract Classes

1. Chapter Introduction

In Chapter 15, we learned that a class can only inherit from ONE parent class (Single Inheritance). But what if a Smartphone is both a Phone AND a Camera AND a GPS? To solve this, OOP relies on Interfaces and Abstract Classes. These allow us to define "Contracts" indicating what an object *should do*, without strictly defining *how* it should do it.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Define and implement Interfaces.
  • Understand how Interfaces bypass single-inheritance limits.
  • Create Abstract Classes.
  • Distinguish between when to use an Interface vs an Abstract Class.

3. What is an Interface?

An Interface is a contract. It defines a set of methods that a class MUST implement if it chooses to adopt the interface. Interfaces cannot hold state (properties with actual backing fields).
kotlin
1234567891011121314151617
// Define the Interface (The Contract)
interface Drivable {
    fun drive() // No body! Just the signature.
    fun stop()
}

// Implement the Interface
class Car : Drivable {
    // We MUST override the methods to fulfill the contract!
    override fun drive() {
        println("Car is moving forward.")
    }

    override fun stop() {
        println("Car brakes applied.")
    }
}

4. Multiple Interfaces (Solving Single Inheritance)

While a class can only inherit from ONE parent class, it can implement an UNLIMITED number of Interfaces!
kotlin
123456789101112131415161718
interface Flyable {
    fun fly()
}

interface Swimmable {
    fun swim()
}

// The Duck class implements two interfaces!
class Duck : Flyable, Swimmable {
    override fun fly() {
        println("Duck is flying!")
    }

    override fun swim() {
        println("Duck is swimming!")
    }
}

*Because Interfaces only provide signatures, there is no confusion about which parent logic to use, making multiple implementation safe.*

5. Interfaces with Default Methods

In modern Kotlin, an Interface *can* actually provide a default implementation for a method. If a class implements the interface, it can choose to use the default or override it.
kotlin
12345678
interface Clickable {
    // Default implementation!
    fun click() {
        println("Button was clicked!")
    }
}

class MyButton : Clickable // We don't HAVE to override click() because it has a default!

6. What is an Abstract Class?

An Abstract Class is a hybrid between a standard Class and an Interface.
  • Like an Interface: It cannot be instantiated (you can't do val x = Animal()).
  • Like a regular Class: It can hold state (actual variables).

Use it when you want a base class to provide *some* core logic and state, but force the child classes to fill in the missing pieces.

kotlin
12345678910111213141516171819202122
abstract class Shape {
    var name: String = "Generic Shape" // It holds state!

    // Abstract method: Has no body. Child MUST override it.
    abstract fun calculateArea(): Double 
    
    // Standard method: Child inherits this automatically.
    fun printInfo() {
        println("This is a $name")
    }
}

// Circle MUST provide calculateArea()
class Circle(val radius: Double) : Shape() {
    init {
        name = "Circle"
    }

    override fun calculateArea(): Double {
        return 3.14 * radius * radius
    }
}

7. Interface vs Abstract Class Comparison

FeatureInterfaceAbstract Class
Instantiate objects?NoNo
Hold actual state (variables)?NoYes
Multiple implementation?YesNo (Single inheritance only)
Use Case:"Can Do" (Behaviors like Clickable)"Is A" (Core identity like Animal)

8. Common Mistakes

  • Trying to instantiate an Interface or Abstract Class: val s = Shape() will trigger a compiler error. They are blueprints for blueprints; they cannot exist as standalone objects.
  • Putting state in an Interface: Writing var count: Int = 0 inside an interface is not allowed. Interfaces describe behavior, not state.

9. Best Practices

  • Code to an Interface: When passing parameters to a function, ask for the Interface, not the concrete class. fun testDrive(vehicle: Drivable) is better than fun testDrive(vehicle: Car), because now the function accepts Cars, Trucks, and Motorcycles!

10. Exercises

  1. 1. Create an interface Playable with a method play().
  1. 2. Create classes Guitar and Piano that implement Playable.
  1. 3. Create a function performConcert(instrument: Playable) that calls play().
  1. 4. Call performConcert() using both instruments in main().

11. MCQs with Answers

Q1. Can you instantiate an Interface directly (e.g., val x = MyInterface())? a) Yes b) No Answer: b) No.

Question 2

How many interfaces can a single Kotlin class implement?

Question 3

If an interface defines a method without a body, what must the implementing class do?

Q4. Can an interface provide a default implementation for a method? a) Yes b) No Answer: a) Yes.

Q5. Can an Abstract Class hold actual state (state variables)? a) Yes b) No Answer: a) Yes.

Q6. Can a class inherit from multiple Abstract Classes? a) Yes b) No, abstract classes are still classes and follow Single Inheritance rules Answer: b) No.

Question 7

When a method in an abstract class is marked abstract, what does it mean?

Q8. Which concept is best used to model an "Is-A" relationship (e.g., A Dog IS AN Animal)? a) Abstract Class b) Interface Answer: a) Abstract Class.

Q9. Which concept is best used to model a "Can-Do" behavior (e.g., A Bird CAN FLY)? a) Abstract Class b) Interface Answer: b) Interface.

Question 10

What is the benefit of making a function parameter an Interface type (e.g., fun handle(item: Clickable))?

12. Interview Questions

  • Q: Explain the difference between an Interface and an Abstract Class. When would you use one over the other?
  • Q: How do Interfaces solve the problem of Multiple Inheritance in Kotlin?

13. Summary

Interfaces and Abstract classes provide the architectural backbone for large applications. Abstract classes provide a shared core identity and state, while Interfaces apply flexible, modular behaviors across entirely unrelated classes. Mastering these allows you to utilize Polymorphism to write code that is extremely reusable.

14. Next Chapter Recommendation

We have written a lot of code to define basic data structures. Kotlin has a feature designed specifically to eliminate boilerplate when creating classes that just hold data. In Chapter 17: Data Classes and Sealed Classes, we will learn how Kotlin revolutionized data modeling.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·