Interfaces

Interfaces allow you to store abstract methods, method implementations and properties. Unlike classes, interfaces do not store information about the state of application processes. Instead, interfaces often provide a template for a given application unit or process. In many programming languages including Java and Kotlin, a class can inherit the data from multiple interfaces.

Abstract methods

Interfaces can contain abstract methods, which are methods that contain a signature (name and parameters) but no implementation (no method body). Classes can inherit the data from interfaces and implement their abstract methods according to their needs. For example, the below Kotlin code defines an interface called House. The House interface contains an abstract method called getAddress, which is implemented by the Person class. Other classes that inherit the House interface could implement the getAddress method differently:

interface House {
	// Abstract method
	fun getAddress()
}
				
class Person: House {
	override fun getAddress() {
		println("12 Rosemary Way")
	}
}

fun main(args: Array<String>) {
	// Prints: 12 Rosemary Way
	Person().getAddress()
}

Default methods

In Kotlin and Java (version 8 and onwards), you can define methods with default implementations. Any inheriting classes can then access and run the method, and even provide additional implementation instructions if required. For example, the below Kotlin code shows how to define an interface method called getAddress that prints a line to the console. The Person class inherits the getAddress method from the interface and provides an additional line to be printed to the console also. Hence, when the getAddress method is called via the Person class, two lines will be printed to the console.

interface House {
	fun getAddress() {
		println("12 Rosemary Way")
	}
}
				
class Person: House {
	override fun getAddress() {
		super.getAddress()
		println("Bristol")
	}
}

fun main(args: Array<String>) {
	// Prints: 12 Rosemary Way
	// Bristol
	Person().getAddress()
}

Interface properties

Interfaces can contain properties, and those properties can be either abstract or pre-implemented. Abstract properties must be implemented by the inheriting class. For example, the below Kotlin code defines an interface called House that contains an abstract property called houseNumber and a pre-implemented property called city. Inheriting classes must override the houseNumber property and assign it a value, but the city property is already implemented by the interface.

interface House {
	// Abstract property
	val houseNumber: Int
	
	// Implemented property
	val city: String
		get() = "Bristol"
}
				
class Person: House {
	// Implement the abstract property
	override val houseNumber = 12
	
	fun getAddress() {
		// city is already implemented by the interface
		println("$houseNumber Rosemary Way, $city")
	}
}

fun main(args: Array<String>) {
	// Prints: 12 Rosemary Way, Bristol
	Person().getAddress()
}