Interface in Kotlin : Create and Handle Properties in Kotlin
An interface in Kotlin is a blueprint of a class, outlining a set of methods that the implementing classes must define. Unlike abstract classes, interfaces cannot contain fields or store state; they solely focus on method signatures and constant properties. By defining an interface, you create a contract that other classes must fulfill, ensuring consistent behavior across multiple implementations. Let’s explore the use of interface in Kotlin programming language.
In Kotlin, interfaces are capable of housing both abstract method declarations and method implementations. The key distinction between interfaces and abstract classes lies in their inability to store state. While interfaces may include properties, these must either be abstract or come with provided accessor implementations.
How to create an Interface in Kotlin?
In Kotlin, you create an interface using the keyword “interface“. we define the method signatures that any class implementing the interface should override.
interface MyData{
fun display()
fun getData()
}
Let’s implement an interface:
Implementing an Interface
A class or an object can implement one or more interfaces
// implementing interface
class RootData : MyData{
override fun display() {
TODO("Not yet implemented")
}
override fun getData() {
TODO("Not yet implemented")
}
}
An example for Kotlin Interface:
Open the Kotlin Playground and write the following program:
interface MyData{
fun display()
fun getData()
}
// implementing interface
class RootData : MyData{
override fun display() {
println("I am showing data")
}
override fun getData() {
println("I am getting data")
}
}
fun main() {
val root = RootData()
root.getData()
root.display()
}
Output
I am getting data
I am showing data
Let’s create a simple example of an interface called Shape to understand the concept better. let’s implement the Shape interface in two classes: Circle and Rectangle
interface Shape {
fun calculateArea(): Double
fun calculatePerimeter(): Double
}
class Circle(private val radius: Double) : Shape {
override fun calculateArea(): Double {
return Math.PI * radius * radius
}
override fun calculatePerimeter(): Double {
return 2 * Math.PI * radius
}
}
class Rectangle(private val length: Double,
private val width:Double
): Shape{
override fun calculateArea(): Double {
return length * width
}
override fun calculatePerimeter(): Double {
return 2 * (length + width)
}
}
fun main() {
val circle = Circle(10.0)
println("Area: ${circle.calculateArea()}")
println("Perimeter ${circle.calculatePerimeter()}")
val rectangle = Rectangle(13.0,40.0)
println("Area : ${rectangle.calculateArea()}")
println("Perimeter : ${rectangle.calculatePerimeter()}")
}
Area: 314.1592653589793
Perimeter 62.83185307179586
Area : 520.0
Perimeter : 106.0
Handling Properties in Interfaces
In Kotlin interfaces, you have the option to declare properties. These properties can be either abstract, leaving their accessors implementation to the implementing class, or they can directly provide implementations for accessors within the interface itself. However, it’s important to note that properties declared in interfaces cannot have backing fields. Consequently, the accessors declared in interfaces cannot reference these properties directly.
Let’s create a Dog Interface:
interface Dog{
val age: Int // abstract
val breed:String
get() = "Labrador"
fun bow(){
println(age)
}
}
class Puppy : Dog{
override val age: Int = 1
override val breed: String
get() = "Pugg"
fun puppyBow()
{
bow()
println(breed)
}
}
Example program (Complete code):
interface Dog{
val age: Int // abstract
val breed:String
get() = "Labrador"
fun bow(){
println(age)
}
}
class Puppy : Dog{
override val age: Int = 1
override val breed: String
get() = "Pugg"
fun puppyBow()
{
bow()
println(breed)
}
}
fun main() {
val puppy = Puppy()
puppy.puppyBow()
}
Output
1
Pugg
One of the main benefits of using Kotlin interfaces is the ability to achieve code reusability. By implementing interfaces, classes can inherit behavior from multiple sources, fostering a modular and organized codebase. Additionally, classes can implement multiple interfaces, allowing developers to mix and match functionality as needed.
Happy coding!