Kotlin Notes Help

Interfaces

Interfaces in Kotlin can contain declarations of abstract methods, as well as method implementations.

What makes them different from abstract classes is that interfaces cannot store state.

They can have properties, but these need to be abstract or provide accessor implementations.

interface MyInterface { fun bar() fun foo() { // optional body } }

Implementing interfaces

class Child : MyInterface { override fun bar() { // body } }

Properties in interfaces

You can declare properties in interfaces.

A property declared in an interface can either be abstract or provide implementations for accessors.

Properties declared in interfaces can't have backing fields, and therefore accessors declared in interfaces can't reference them:

interface MyInterface { val prop: Int // abstract val propertyWithImplementation: String get() = "foo" fun foo() { print(prop) } } class Child : MyInterface { override val prop: Int = 29 }

Interfaces Inheritance

An interface can derive from other interfaces, meaning it can both provide implementations for their members and declare new functions and properties.

Quite naturally, classes implementing such an interface are only required to define the missing implementations:

interface Named { val name: String } interface Person : Named { val firstName: String val lastName: String override val name: String get() = "$firstName $lastName" } data class Employee( // implementing 'name' is not required override val firstName: String, override val lastName: String, val position: Position ) : Person

Resolving overriding conflicts

When you declare many types in your supertype list, you may inherit more than one implementation of the same method:

Scenario 1

We don't need to override the methods which have a default implementation in the interface

interface First { fun foo() { println("First") } fun bar() { println("A") } } class Test : First { fun test() { println("test") } }

Scenario 2

We need to override the methods which doesn't have a default implementation in the interface

interface Second { fun foo() { println("Second") } fun bar() } class Test : Second { override fun bar() { println("T") } }

Scenario 3

We can override the methods which have a default implementation in the interface

interface First { fun foo() { println("First") } fun bar() { println("A") } } class Test : First { override fun foo() { println("Test") } override fun bar() { println("T") } }

Scenario 4

When a class inherits from more than one interface and those interfaces have the same method (with different implementations)

Then we need to provide the implementation of those methods(methods that are present in different interfaces) in our class

interface First { fun foo() { println("First") } fun bar() { println("A") } } interface Second { fun foo() { println("Second") } } class Test : First, Second { override fun foo() { println("Test") } }
interface First { fun foo() { println("First") } fun bar() { println("A") } } interface Second { fun foo() { println("Second") } fun bar() } class Test : First, Second { override fun foo() { println("Test") } override fun bar() { println("T") } }

Scenario 5

interface First { fun foo() { println("First") } fun bar() { println("A") } } interface Second { fun foo() { println("Second") } fun bar() } class Test : First, Second { override fun foo() { super<First>.foo() super<Second>.foo() } override fun bar() { super<First>.bar() } }
Last modified: 26 February 2024