Kotlin Interfaces

Kotlin Interfaces define a contract that classes can implement. An interface can declare abstract properties, abstract functions, and functions with default implementation. A class that implements the interface must provide the missing implementation for all abstract members.

Interfaces are useful when different classes should expose the same behavior without forcing them to inherit from the same superclass. For example, Car, Boat, and Aeroplane can all implement a common Vehicle interface, even though they may work differently internally.

If a class is implementing an interface, the class is making a promise that the abstract methods in the interface shall be implemented. Compiler makes sure that this promise is not broken and if it does, compiler throws an error and stops.

Kotlin interface syntax with properties and functions

The following program is an example for basic Kotlin Interface with variables, abstract methods, and non-abstract methods.

Kotlin Program – example.kt

</>
Copy
interface Vehicle {
    // uninitialized variables
    var name : String
    var medium : String

    // non-abstract method
    fun runsWhere() {
        println("The vehicle, $name, runs in $medium")
    }

    // abstract method
    fun howItRuns()
}
  • interface keyword is used to define an interface.
  • Kotlin Interface cannot have initialized variables.
  • Kotlin Interface can have non-abstract and abstract methods.

In Kotlin, interface properties do not store state directly. An interface can require a property, such as name, but the implementing class must provide where that property value comes from. An interface can also define a property with a custom getter, as long as it does not use a backing field.

</>
Copy
interface PrintableVehicle {
    val name: String

    val label: String
        get() = "Vehicle: $name"

    fun printLabel() {
        println(label)
    }
}

Implement a Kotlin interface in a class

Kotlin Classes can implement an interface and these classes should override the abstract methods and variables of Kotlin Interface. Following is an example where Aeroplane class implements Vehicle interface.

Kotlin Program – example.kt

</>
Copy
/**
 * Interface
 */
interface Vehicle {
    // uninitialized variables
    var name : String
    var medium : String

    // non-abstract method
    fun runsWhere() {
        println("The vehicle, $name, runs in $medium")
    }

    // abstract method
    fun howItRuns()
}

/**
 * implementing interface
 */
class Aeroplane : Vehicle {
    // override abstract variables and functions of interface
    override var name:String = "Aeroplane"
    override var medium: String = "air"

    override fun howItRuns() {
        println("$name flies based on buoyancy force.")
    }
}

fun main(args: Array<String>) {
    var vehicle1 = Aeroplane()
    vehicle1.runsWhere()
    vehicle1.howItRuns()
}

Output

The vehicle, Aeroplane, runs in air
Aeroplane flies based on buoyancy force.

The class name is followed by a colon and the interface name: class Aeroplane : Vehicle. The override keyword is required for each abstract property or function implemented from the interface. This makes the contract clear both to the compiler and to anyone reading the code.

Kotlin interface default function implementation

An interface function can have a body. Such a function provides default behavior, so implementing classes can use it as-is or override it when they need custom behavior.

</>
Copy
interface Logger {
    fun log(message: String) {
        println("Log: $message")
    }
}

class ConsoleLogger : Logger

fun main() {
    val logger = ConsoleLogger()
    logger.log("Application started")
}

Output

Log: Application started

Here, ConsoleLogger does not define log(), because the interface already provides a default implementation. This is one of the main differences between an interface with default methods and a purely abstract contract.

Override default interface methods in Kotlin

A class can override a default interface method when the default behavior is not suitable. The override keyword is still required.

</>
Copy
interface PaymentProcessor {
    fun process(amount: Double) {
        println("Processing payment of $amount")
    }
}

class CardPaymentProcessor : PaymentProcessor {
    override fun process(amount: Double) {
        println("Processing card payment of $amount")
    }
}

fun main() {
    val processor = CardPaymentProcessor()
    processor.process(250.0)
}

Output

Processing card payment of 250.0

Implement multiple Kotlin interfaces in one class

A Kotlin Class can implement multiple Kotlin Interfaces. All the abstract methods and variables of the interfaces being implemented must be overridden in the class.

In the following example, Aeroplane class implement two interfaces:Vehicle and ArielVehicle. So, Aeroplane has to implement all the abstract members of the interfaces Vehicle and ArielVehicle.

Kotlin Program – example.kt

</>
Copy
/**
 * Interface
 */
interface Vehicle {
    // uninitialized variables
    var name : String
    var medium : String

    // non-abstract method
    fun runsWhere() {
        println("The vehicle, $name, runs in $medium")
    }

    // abstract method
    fun howItRuns()
}

/**
 * Another Interface
 */
interface ArielVehicle {
    // uninitialized variables
    var maximum_altitude:Int // in feet
}

/**
 * implementing interface
 */
class Aeroplane : Vehicle, ArielVehicle {
    // override abstract variables and functions of interface
    override var name:String = "Aeroplane"
    override var medium: String = "air"
    override var maximum_altitude: Int = 10000

    override fun howItRuns() {
        println("$name flies based on buoyancy force.")
    }
}

The class lists the interfaces after the colon, separated by commas. Kotlin allows a class to extend only one class, but it can implement many interfaces. This makes interfaces useful for composing capabilities such as Printable, Serializable, Clickable, or Payable.

Resolve same function names from multiple Kotlin interfaces

If two interfaces provide default implementations for the same function signature, the implementing class must override that function. This removes ambiguity. Inside the override, you can call a specific interface implementation using super<InterfaceName>.functionName().

</>
Copy
interface EngineVehicle {
    fun start() {
        println("Starting engine vehicle")
    }
}

interface ElectricVehicle {
    fun start() {
        println("Starting electric vehicle")
    }
}

class HybridCar : EngineVehicle, ElectricVehicle {
    override fun start() {
        super<EngineVehicle>.start()
        super<ElectricVehicle>.start()
        println("Hybrid car is ready")
    }
}

fun main() {
    val car = HybridCar()
    car.start()
}

Output

Starting engine vehicle
Starting electric vehicle
Hybrid car is ready

Kotlin interfaces versus abstract classes

Kotlin interfaces and abstract classes can both define members that subclasses must implement, but they are used for different design needs.

FeatureKotlin interfaceKotlin abstract class
Inheritance ruleA class can implement multiple interfaces.A class can extend only one abstract class.
StateCannot store state using backing fields.Can store state in properties.
ConstructorCannot have constructors.Can have constructors.
Best useDefine capabilities or contracts.Share common base behavior and state.
ExamplePrintable, Clickable, RunnableBaseActivity, Shape, Repository

Use a Kotlin interface when you want to describe what a type can do. Use an abstract class when related classes need shared state, constructor logic, or a common base implementation.

Common mistakes with Kotlin interface properties

  • Trying to initialize an interface property directly: an interface cannot declare val count = 0 because that would require stored state.
  • Forgetting the override keyword: Kotlin requires override when implementing interface members.
  • Confusing interface implementation with class inheritance: use commas for multiple interfaces, such as class Report : Printable, Exportable.
  • Ignoring name conflicts: when two interfaces define the same default method, the class must override it explicitly.
  • Putting unrelated responsibilities into one interface: prefer small focused interfaces instead of one large interface with many unrelated methods.

When to use Kotlin interfaces in real programs

Use Kotlin interfaces when multiple classes need to follow the same contract but do not need the same parent class. Interfaces are common in Android development, service layers, callbacks, repositories, testing, and dependency injection.

</>
Copy
interface UserRepository {
    fun findUserName(id: Int): String
}

class LocalUserRepository : UserRepository {
    override fun findUserName(id: Int): String {
        return "Local user $id"
    }
}

class RemoteUserRepository : UserRepository {
    override fun findUserName(id: Int): String {
        return "Remote user $id"
    }
}

fun printUser(repository: UserRepository, id: Int) {
    println(repository.findUserName(id))
}

fun main() {
    printUser(LocalUserRepository(), 1)
    printUser(RemoteUserRepository(), 2)
}

Output

Local user 1
Remote user 2

The function printUser() depends on the interface UserRepository, not on a specific class. This makes it easier to replace one implementation with another.

Kotlin interface FAQ

Can Kotlin interfaces have method bodies?

Yes. A Kotlin interface can contain functions with default implementation. A class can use the default behavior or override it.

Can Kotlin interfaces have properties?

Yes. Kotlin interfaces can declare properties. However, they cannot store state using backing fields. The implementing class must provide the property value, or the interface can provide a custom getter.

Can a Kotlin class implement more than one interface?

Yes. A Kotlin class can implement multiple interfaces by listing them after the colon and separating them with commas.

What happens if two Kotlin interfaces have the same default method?

The class must override that method. Inside the override, it can call a specific interface version using syntax such as super<FirstInterface>.methodName().

Should I use a Kotlin interface or an abstract class?

Use an interface for a capability or contract that many unrelated classes can implement. Use an abstract class when subclasses need shared state, constructor logic, or common base behavior.

Kotlin interface editorial QA checklist

  • Does the tutorial clearly explain that Kotlin interfaces define contracts for implementing classes?
  • Does every new Kotlin example use the override keyword where an interface member is implemented?
  • Does the tutorial distinguish abstract interface members from default interface methods?
  • Does it explain why interface properties cannot store backing-field state?
  • Does the multiple-interface section show how conflicts are resolved with super<InterfaceName>?

Kotlin interface key takeaways

Kotlin interfaces are used to define a common contract for classes. They can declare abstract properties and functions, provide default function implementations, and be implemented along with other interfaces. A class that implements an interface must override all abstract members, and it must explicitly resolve conflicts when multiple interfaces provide the same default method.

You can also refer to the official Kotlin interfaces documentation for language-specific details. In this Kotlin Tutorial, we have learnt about Kotlin Interfaces and how to implement them. In our next tutorial, we shall learn Kotlin Abstract Classes.