Design Converter
Education
Last updated on May 6, 2024
Last updated on May 6, 2024
Engineering Manager
Engineering Manager at DhiWise with a knack for advanced algorithms and system design. With 10 years of experience leading teams, I thrive on solving complex problems, optimizing code, and mentoring future engineers to drive innovation.
Software Development Executive - II
A Flutter and iOS developer.
Kotlin, an object-oriented programming language, offers numerous features. Among these, "Kotlin Interfaces" is a key component supporting code reusability and encapsulation.
In essence, an interface is a reference type in Kotlin similar to a class. It is a collection of abstract methods and properties, alongside default implementations. This concept emulates the idea of multiple inheritances, a feature not directly available in Kotlin.
Interfaces enhance the versatility of the code, offering a structured way to commit a class to perform certain actions. However, unlike an abstract class, an interface cannot store state and cannot be instantiated directly.
Creating a basic interface in Kotlin is straightforward, and defined using the interface keyword. An "Interface" comprises abstract methods and properties, and can also define non-abstract methods, also known as "default implementations". Refer to the example below to understand the "Interface MyInterface":
1interface MyInterface { 2 fun bar() 3 fun foo() { 4 // optional body 5 } 6}
In this 'MyInterface', two functions are declared: 'fun bar' and 'fun foo'. While 'fun bar' is an abstract method (having no body), 'fun foo' provides a default implementation (having an optional body). This exemplifies code flexibility, permitting various classes to implement the same interface, adhering to the same contract, but offering custom implementation details.
Abstract methods form an essential part of Kotlin Interfaces. These methods with no body need to be overridden and implemented in any class implementing the said interface. Declare abstract methods with the 'fun' keyword, followed by the method name, and end the declaration without providing a body. As an example, look at:
1interface Rectangle { 2 fun area() 3}
Here the 'fun area' method is an abstract method with no assigned body or default value.
A class or object in Kotlin implements an "Interface" by using the ":" keyword, defining a new class that adheres to the contract of the interface. For instance, consider the class 'Child' with the 'MyInterface':
1class Child : MyInterface { 2 override fun bar() { 3 // body 4 } 5}
The 'Child' class obeys the behavior defined by 'MyInterface'. It provides an implementation for 'fun bar' which was abstract in the interface. The 'override' keyword is crucial here as it communicates that 'fun bar' is not new but overrides a function from the superior interface.
Kotlin enables implementing multiple interfaces in the same class, allowing a single class to imitate the behavior of multiple interfaces.
1interface A { 2 fun foo() 3} 4interface B { 5 fun bar() 6} 7 8class Child : A, B { 9 override fun foo() { 10 //body 11 } 12 override fun bar() { 13 //body 14 } 15}
In this example, 'Child' class implements 'A' and 'B' interfaces, meaning it must provide the implementation of 'fun foo' from 'A' and 'fun bar' from 'B'.
Properties, essential elements of classes in Kotlin, can also be declared within interfaces, which can provide accessor implementations. However, not having backing fields, such properties require careful handling:
1interface MyInterface { 2 val prop: Int // abstract 3 4 val propertyWithImplementation: String 5 get() = "foo" 6}
In the code snippet, 'val prop: Int' is an abstract property and must be overridden. 'propertyWithImplementation' has an accessor implementation making 'foo' its default value. Any class implementing 'MyInterface' references 'foo' when 'propertyWithImplementation' is called.
Abstract properties form a cardinal part of Kotlin interface, with no initialization or accessor implementation in the interface, but requiring an implementation in the derived class:
1interface MyInterface { 2 val length: Int 3} 4class MyClass: MyInterface { 5 override val length: Int = 10 6}
Here, 'val length' is an abstract property in MyInterface, and 'MyClass' provides a value of '10' for it, thus offering an implementation for the abstract property.
The principle of inheritance applies to interfaces in Kotlin. An interface can derive from one or more other interfaces, the same way classes extend abstract classes. This means it could both provide implementations for their members and declare new functions and properties:
1interface Shape { 2 fun area() 3} 4interface Rectangle : Shape { 5 fun perimeter() 6}
Here, the interface 'Rectangle' inherits from 'Shape' and thus, any class implementing 'Rectangle' must provide implementations for both 'Shape's abstract method 'fun area' and 'Rectangle's 'fun perimeter'.
A pertinent point of confusion among beginners often stems from differentiating between Kotlin's "Abstract Classes" and "Interfaces". While both are unable to store state, they showcase marked differences:
• "Abstract Classes" can contain constructor and destructor declarations, whereas "Interfaces" cannot.
• A class can implement more than one interface, whereas it can only inherit from one abstract class.
• Abstract classes can provide member fields, but interfaces are limited to property declarations.
Overriding conflicts arise when a class implements more than one interface with the same function or property. To resolve such overriding conflicts, Kotlin necessitates explicit mention of which method to invoke:
1interface A { 2 fun foo() { print("A") } 3} 4 5interface B { 6 fun foo() { print("B") } 7} 8 9class C: A, B { 10 override fun foo() { 11 super<A>.foo() 12 super<B>.foo() 13 } 14}
In the example above, both 'A' and 'B' interfaces have the method 'fun foo'. Implementing class 'C' overrides 'foo' and explicitly calls both 'A' and 'B' versions of 'fun foo'.
Introduced in Kotlin 1.4, the Function Interface enhances the simplicity and conciseness of Kotlin code. A function interface has a single abstract method but can contain several other non-abstract methods. This single-method interface can be implemented using lambda expressions:
1fun interface MyFunInterface { 2 fun execute() 3} 4 5fun main() { 6 val obj: MyFunInterface = MyFunInterface { 7 println("execute function called") 8 } 9 obj.execute() 10}
In this example, the function interface 'MyFunInterface' has a single abstract method 'execute'. When we create an instance 'obj' of the interface, we provide an implementation of 'execute' in the form of a lambda expression.
Kotlin interfaces are crucial for navigating the limitations of single inheritance in object-oriented programming. They help develop a contract for classes, detailing settled behavior with abstract methods.
Interfaces allow multiple behaviors without engaging in multiple inheritance, thus enabling multiple implementations. This advantage aids in the creation of customizable and reusable code components, enhancing the modularity and organization of your codebase. Further, they are flexible enough to contain default implementations, allowing structures otherwise specific to implementing classes.
However, remember that interfaces cannot store state. Any declared properties must be abstract or provide accessor implementations. While seemingly complex, Kotlin interfaces distill down to effective utilization of contract-based programming.
That's a wrap on our deep dive into Kotlin interfaces! Keep coding, exploring, and learning!
Tired of manually designing screens, coding on weekends, and technical debt? Let DhiWise handle it for you!
You can build an e-commerce store, healthcare app, portfolio, blogging website, social media or admin panel right away. Use our library of 40+ pre-built free templates to create your first application using DhiWise.