Introduction
Interfaces in Kotlin define a contract that classes can implement. They can contain abstract methods as well as method implementations. Unlike classes, interfaces cannot store state, and a class can implement multiple interfaces, which helps in achieving multiple inheritances.
Defining an Interface
To define an interface in Kotlin, use the interface
keyword. Interfaces can contain both abstract methods (which do not have a body) and concrete methods (which have a default implementation).
Syntax
interface InterfaceName {
fun abstractMethod()
fun concreteMethod() {
// Default implementation
}
}
Example
fun main() {
val myClass = MyClass()
myClass.abstractMethod()
myClass.concreteMethod()
}
interface MyInterface {
fun abstractMethod()
fun concreteMethod() {
println("This is a concrete method in an interface.")
}
}
class MyClass : MyInterface {
override fun abstractMethod() {
println("This is an implementation of the abstract method.")
}
}
Explanation:
interface MyInterface { ... }
: Defines an interfaceMyInterface
with an abstract methodabstractMethod
and a concrete methodconcreteMethod
.class MyClass : MyInterface { ... }
: Implements theMyInterface
interface.override fun abstractMethod() { ... }
: Provides an implementation for the abstract method in theMyClass
class.
Output:
This is an implementation of the abstract method.
This is a concrete method in an interface.
Properties in Interfaces
Interfaces in Kotlin can also define properties. These properties can either be abstract (without a body) or have default implementations.
Example
fun main() {
val myClass = MyClass()
myClass.abstractMethod()
myClass.concreteMethod()
println("Property value: ${myClass.property}")
}
interface MyInterface {
val property: String
fun abstractMethod()
fun concreteMethod() {
println("This is a concrete method in an interface.")
}
}
class MyClass : MyInterface {
override val property: String = "Hello, Kotlin!"
override fun abstractMethod() {
println("This is an implementation of the abstract method.")
}
}
Explanation:
val property: String
: Defines an abstract property in theMyInterface
interface.override val property: String = "Hello, Kotlin!"
: Provides an implementation for the abstract property in theMyClass
class.
Output:
This is an implementation of the abstract method.
This is a concrete method in an interface.
Property value: Hello, Kotlin!
Implementing Multiple Interfaces
A class in Kotlin can implement multiple interfaces. When a class implements multiple interfaces, it must provide implementations for all the abstract methods in the interfaces.
Example
fun main() {
val myClass = MyClass()
myClass.abstractMethodA()
myClass.abstractMethodB()
myClass.concreteMethodA()
myClass.concreteMethodB()
}
interface InterfaceA {
fun abstractMethodA()
fun concreteMethodA() {
println("This is a concrete method in InterfaceA.")
}
}
interface InterfaceB {
fun abstractMethodB()
fun concreteMethodB() {
println("This is a concrete method in InterfaceB.")
}
}
class MyClass : InterfaceA, InterfaceB {
override fun abstractMethodA() {
println("This is an implementation of abstractMethodA.")
}
override fun abstractMethodB() {
println("This is an implementation of abstractMethodB.")
}
}
Explanation:
interface InterfaceA { ... }
andinterface InterfaceB { ... }
: Define two interfaces with both abstract and concrete methods.class MyClass : InterfaceA, InterfaceB { ... }
: Implements bothInterfaceA
andInterfaceB
.override fun abstractMethodA() { ... }
andoverride fun abstractMethodB() { ... }
: Provide implementations for the abstract methods from both interfaces.
Output:
This is an implementation of abstractMethodA.
This is an implementation of abstractMethodB.
This is a concrete method in InterfaceA.
This is a concrete method in InterfaceB.
Resolving Conflicts in Multiple Interfaces
When implementing multiple interfaces, a class may encounter conflicts if the interfaces contain methods with the same name. Kotlin requires you to explicitly override the conflicting methods and resolve the conflicts.
Example
fun main() {
val myClass = MyClass()
myClass.commonMethod()
}
interface InterfaceA {
fun commonMethod() {
println("Common method in InterfaceA")
}
}
interface InterfaceB {
fun commonMethod() {
println("Common method in InterfaceB")
}
}
class MyClass : InterfaceA, InterfaceB {
override fun commonMethod() {
super<InterfaceA>.commonMethod()
super<InterfaceB>.commonMethod()
}
}
Explanation:
interface InterfaceA { ... }
andinterface InterfaceB { ... }
: Both interfaces define a method namedcommonMethod
.override fun commonMethod() { ... }
: TheMyClass
class provides an implementation for the conflicting method and explicitly calls the implementations from both interfaces usingsuper<InterfaceA>
andsuper<InterfaceB>
.
Output:
Common method in InterfaceA
Common method in InterfaceB
Example Program with Interfaces
Here is an example program that demonstrates various aspects of interfaces in Kotlin:
fun main() {
val myClass = MyClass()
myClass.abstractMethod()
myClass.concreteMethod()
println("Property value: ${myClass.property}")
val anotherClass = AnotherClass()
anotherClass.abstractMethodA()
anotherClass.abstractMethodB()
anotherClass.concreteMethodA()
anotherClass.concreteMethodB()
}
interface MyInterface {
val property: String
fun abstractMethod()
fun concreteMethod() {
println("This is a concrete method in an interface.")
}
}
class MyClass : MyInterface {
override val property: String = "Hello, Kotlin!"
override fun abstractMethod() {
println("This is an implementation of the abstract method.")
}
}
interface InterfaceA {
fun abstractMethodA()
fun concreteMethodA() {
println("This is a concrete method in InterfaceA.")
}
}
interface InterfaceB {
fun abstractMethodB()
fun concreteMethodB() {
println("This is a concrete method in InterfaceB.")
}
}
class AnotherClass : InterfaceA, InterfaceB {
override fun abstractMethodA() {
println("This is an implementation of abstractMethodA.")
}
override fun abstractMethodB() {
println("This is an implementation of abstractMethodB.")
}
}
Output:
This is an implementation of the abstract method.
This is a concrete method in an interface.
Property value: Hello, Kotlin!
This is an implementation of abstractMethodA.
This is an implementation of abstractMethodB.
This is a concrete method in InterfaceA.
This is a concrete method in InterfaceB.
Conclusion
In this chapter, you learned about interfaces in Kotlin, including how to define interfaces, implement interfaces in classes, use properties in interfaces, implement multiple interfaces, and resolve conflicts in multiple interfaces. Interfaces are essential for achieving abstraction and multiple inheritance in Kotlin, making your code more modular and reusable. Understanding and applying interfaces is crucial for writing robust and maintainable Kotlin programs.