Extensions in Kotlin
Have you ever felt some useful functionality missing in an existing class?
The class could be in the libraries provided by language also.
“Yes”
What exactly you do to add that functionality in the class?
“Extend the class and add the method and then use my own extended class”
If so, Kotlin extensions can definitely make your life easier.
This post was originally posted at https://agrawalsuneet.github.io/blogs/extensions-in-kotlin/ and reposted on Medium on 20th Jul 2018.
Kotlin provides the ability to extend a class with new functionality without having to inherit from the class or use any type of design pattern such as Decorator. This is done using a special declaration called extensions
. These extensions basically add some functionality in an existing class without extending the class.
And how do we use it?
I will explain this but before that, keep in mind that Kotlin supports both, extension functions and extension properties (Without backing field). Let’s understand them one by one.
Extension Functions
To declare an extension function, we need to prefix its name with a receiver type, i.e. the type being extended or the class name.
Let’s say we want to add a function in the List
Interface implementation which returns the element at the mid position of the list.
fun <T> List<T>.midElement(): T {
if (isEmpty())
throw NoSuchElementException("List is empty.")
return this[size / 2]
}
//to call this methodvar list = listOf<Int>(1, 2, 3, 4, 5)
var mid = list.midElement()//or var arrayList = arrayListOf(5, 4, 3, 2, 1)
var mid = arrayList.midElement()
So what we are doing here?
We are adding a method named midElement
in the List
implementation which returns us the element at the mid position of the list. This method throws NoSuchElementException
if the list is empty.
Later this midElement
method can be called with any normal List object.
Let’s take another example of our very favorite Toast
class in Android.Toast
class is used to show a message at the bottom half of the screen in Android for a long or short duration.
The native code to show a Toast in Android is
Toast.makeText(this, “Hello”, Toast.LENGTH_SHORT).show()
The above code calls a static method makeText
of Toast
class with three parameters (reference of the current Context
class, the CharSequence
to be displayed and the Int
duration for which the toast to be shown). The static method returns the Toast
class object to which we call the show
method.
Now to make the call easy to this Toast
from any class which extends the Context
class directly or indirectly, we can create an extension method of Context
class which will do the exact same.
fun Context.showToast(text: CharSequence, duration: Int = Toast.LENGTH_SHORT) {
Toast.makeText(this, text, duration).show()
}//to call this method from any context extending class
showToast("Hello")
How are extensions resolved?
Statically.
Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type.
The extension functions dispatched statically. That means the extension function which will be called is determined by the type of the expression on which the function is invoked, not by the type of the result of evaluating that expression at runtime. In short, they are not virtual by receiver type.
Let me explain.
Please continue reading at https://agrawalsuneet.github.io/blogs/extensions-in-kotlin/
Reference: Kotlin Docs
Update
Next: Extensions as Members