Kotlin Interfaces explained. Interfaces vs Abstract classes

Hitesh Kohli
4 min readJan 25, 2025

--

Photo by Kelly Sikkema on Unsplash

Interfaces are a feature in Kotlin that enables developers to define contracts for classes without enforcing inheritance. By combining abstract methods and default implementations, interfaces provide flexibility and modularity.

In this blog, we’ll explore what interfaces are, how to use them, and how they differ from abstract classes. By the end, you’ll have a solid understanding of when and why to use interfaces in Kotlin.

What is an Interface?

In Kotlin, an interface can contain both declarations of abstract methods (methods without implementation) and methods with implementation. It serves as a blueprint for classes, allowing them to define shared behaviours.

Definition:

An interface in Kotlin can contain declarations of abstract methods and method implementations.

Here’s an example:

interface Vehicle {
fun engine()
}
class Car : Vehicle {
override fun engine() {
println("Engine Starting in Car")
}
}

In this example:

  • Vehicle defines a contract that any implementing class must follow.
  • Car implements the Vehicle interface and provides the implementation for the engine() method.

Why Use Interfaces?

Interfaces are useful when you need to define shared functionality across unrelated classes. For instance, consider the example below:

interface MaintenanceInterface {
fun needMaintenanceTimePeriod()
}
class Car : MaintenanceInterface {
override fun needMaintenanceTimePeriod() {
println("Maintenance Period - Every 6 months")
}
}
class AirConditioner : MaintenanceInterface {
override fun needMaintenanceTimePeriod() {
println("Maintenance Period - Every 1 Year")
}
}

Here:

  • Both Car and AirConditioner are unrelated entities, yet they share a common functionality: maintenance.
  • Using an interface, we define a common contract without forcing inheritance, promoting code reusability and flexibility.

Interface vs. Abstract Classes

Although interfaces and abstract classes may seem similar, they serve different purposes. Abstract classes are designed as a base class for inheritance, while interfaces define contracts or capabilities.

Abstract Class Example:

abstract class Animal(val name: String) {
abstract fun makeSound()
fun eat() {
println("$name is eating.")
}
}
class Dog(name: String) : Animal(name) {
override fun makeSound() {
println("Bark!")
}
}
class Cat(name: String) : Animal(name) {
override fun makeSound() {
println("Meow!")
}
}

Key Differences:

Understanding the Limitations of Interfaces

No Backing Fields

In Kotlin, properties in an interface cannot have backing fields. This means you cannot store values directly in an interface.

Example:

interface Vehicle {
var tyres: Int
get() = 4
set(value) {
field = value // ERROR: Interfaces cannot have a backing field
}
}

Advanced Interface Features

Multiple Interface Implementation

Kotlin allows a class to implement multiple interfaces. This is useful when you need a class to support multiple capabilities.

interface A {
fun methodA() {
println("Method A from Interface A")
}
}
interface B {
fun methodB() {
println("Method B from Interface B")
}
}
class MyClass : A, Bfun main() {
val obj = MyClass()
obj.methodA()
obj.methodB()
}

Conflict Resolution in Multiple Interfaces

When implementing multiple interfaces with methods of the same name, Kotlin forces you to resolve the conflict by explicitly specifying which implementation to use.

interface A {
fun foo() { print("A") }
fun bar()
}
interface B {
fun foo() { print("B") }
fun bar() { print("bar") }
}
class C : A {
override fun bar() { print("bar") }
}
class D : A, B {
override fun foo() {
super<A>.foo() // Explicitly call A's implementation
super<B>.foo() // Explicitly call B's implementation
}
override fun bar() {
super<B>.bar()
}
}

Best Practices for Using Interfaces:

Follow the Interface Segregation Principle:
Avoid creating large interfaces with too many methods. Instead, split them into smaller, specific interfaces.

Use Interfaces for Capabilities, Not State:
Interfaces define behaviour, while abstract classes define state and behaviour. Use them accordingly.

Ensure Consistency Across Implementations:
All classes implementing an interface must adhere to the contract defined by the interface.

Document Your Interfaces:
Provide clear documentation for what the interface represents and its intended usage.

If you want to understand it in more detail. Here is a video for you:

Conclusion

Interfaces are a cornerstone of Kotlin programming, enabling modularity, flexibility, and reusability. They allow unrelated classes to share common functionality without forcing a rigid inheritance structure. By understanding the nuances of interfaces and their differences from abstract classes, you can write cleaner and more maintainable Kotlin code.

--

--

Hitesh Kohli
Hitesh Kohli

Written by Hitesh Kohli

Hi, my name is Hitesh Kohli, I work at Geeks for Geeks as an Android developer. I love messing around with apps and games.

No responses yet