Kotlin provides ability to extend class with new functionality without having to inherit from class or use any type of design pattern such as Decorator.
Extensions do not modify parent classes! They are just extending it. Extensions do not insert a new function to a class but create a callable inside a class where we are extending. Let’s look at the example (Extensions.kt):
class Parent {
fun doSomething() {
println("Do something...")
}
}
class MyClass {
fun Parent.doSomething() {
this.doSomething()
println("And the extended part.")
}
fun Parent.doSomething(x: Int) {
println("Extended with parameter passed")
}
fun Parent.newStuff() {
println("Extended with new method")
}
fun tryExtensions(parent: Parent) {
with(parent) {
doSomething()
doSomething(5)
newStuff()
}
}
}
Then call it:
val p = Parent()
p.doSomething()
println("- - - - -")
val m = MyClass()
m.tryExtensions(p)
println("- - - - -")
Console output:
Do something...
- - - - -
Do something...
Extended with parameter passed
Extended with new method
- - - - -
Kotlin has ability to extend class properties. Let’s see the example ExtendingProperties.kt:
class ToBeExtended {
val a = 15
}
class ExtendsProperty {
val ToBeExtended.b: Int
get() = 25
fun tryPropertyExtension(e: ToBeExtended) {
println("A: ${e.a}")
println("A: ${e.b}")
}
}
Try it:
val t = ToBeExtended()
val e = ExtendsProperty()
e.tryPropertyExtension(t)
Console output:
A: 15
A: 25
If some class has companion object it is possible to be extended by other class.
Let’s take a look at example ExtendingCompanionObject.kt:
class HasCompanion {
companion object {
val a = 10
fun printA() {
println("A: $a")
}
}
}
class ExtendsCompanioObjectClass {
fun HasCompanion.Companion.printB(){
println("B: ${ a + 100 }")
}
fun tryExtendingCompanionObject(){
HasCompanion.printA()
HasCompanion.printB()
}
}
We call it:
val e = ExtendsCompanioObjectClass()
e.tryExtendingCompanionObject()
Console output:
A: 10
B: 110