Kotlin - Extensions


Kotlin extensions provide the ability to extend a class with new functionality without implementing the inheritance concept by a class or using design pattern such as Decorator. These extensions basically add some functionality in an existing class without extending the class.

The Kotlin extension allows to write new functions for a class from a third-party library without modifying the class. The beauty of the extension functions is that they can be called in the usual way, as if they were methods of the original class and these new functions are called Extension Functions.

Similarly, we can also define extension properties for an existing Kotlin class.

Extension Function

A kotlin extension function is a member function of a class, which is defined outside the class. The created extension functions are used as a regular function inside that class.

Syntax

Following is the syntax to define an extension function. Here, the extension function is declared with using the class name and also with using method name.

fun <class_name>.<method_name>(){
 ....
 function body
}

Example

In function extension, Kotlin allows to define a method outside of the main class. In the following example, we will see how the extension is implemented at the functional level.

class Alien {
   var skills : String = "null"
	
   fun printMySkills() {
      print(skills)
   }		
}
fun main(args: Array<String>) {
   var  a1 = Alien()
   a1.skills = "JAVA"
   //a1.printMySkills()
	
   var  a2 = Alien()
   a2.skills = "SQL"
   //a2.printMySkills()
	
   var  a3 = Alien()
   a3.skills = a1.addMySkills(a2)
   a3.printMySkills()
}
fun Alien.addMySkills(a:Alien):String{
   var a4 = Alien()
   a4.skills = this.skills + " " +a.skills
   return a4.skills
}

In the above example, we don’t have any method inside “Alien” class named as “addMySkills()”, however, we still are implementing the same method somewhere else outside of the class, This is the magic of extension.

When you run the above Kotlin program, it will generate the following output:

JAVA SQL

Extended Library Classes

Kotlin allows to extend the standard library classes as well as user-defined classes. For example, if you need a specialised function for standard Kotlin String class which will return the number of vowels available in the string, such method is not already available in String class but you can use an extension function to accomplish this task.

fun main(args: Array<String>) {
   val str = "Good morning Kotlin"
   
   val result = str.countVowels()
   println("Number of vowels: $result")
}
fun String.countVowels(): Int{
   var vowels = 0
   for (i in 0.. this.length - 1) {
      val ch = this[i]
      if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
         ++vowels
      }
   }
   return vowels; 
}

When you run the above Kotlin program, it will generate the following output:

Number of vowels: 6

Companion Object Extensions

Kotlin provides another mechanism to implement static functionality of Java. This can be achieved using the companion object which is declared inside a class and marked with the companion keyword. Using this mechanism, we can create an object of a class inside a factory method and later we can just call that method using the reference of the class name.

In the following example, we will create a “companion object”.

fun main(args: Array<String>) {
   println("Heyyy!!!"+A.show())
}
class A {
   companion object {
      fun show():String {
         return("You are learning Kotlin from TutorialsPoint.com")
      }
   }
}

When you run the above Kotlin program, it will generate the following output:

Heyyy!!! You are learning Kotlin from TutorialsPoint.com

The above example seems like static in Java, however, in real-time we are creating an object as a member variable of that same class. This is why it is also included under extension property and can be alternatively called as an object extension. You are basically extending the object of the same class to use some of the member functions.

Extension with Nullable Receiver

Kotlin allows to define Extension Functions with a nullable class type. These extension function can be called on a nullable object variable.

To define an extension for Nullable receiver, we just need to add a check for null receiver inside the extension function, and the appropriate value is returned.

fun main(args: Array<String>) {
   var str1 = "Good morning Kotlin"
   var str2 : String? = null
   
   var result = str1.countVowels()
   println("Number of vowels in str1 : $result")
   
   result = str2.countVowels()
   println("Number of vowels in str2 : $result")
}
fun String?.countVowels(): Any{
   if (this == null) return "null"
   
   var vowels = 0
   for (i in 0.. this.length - 1) {
      val ch = this[i]
      if (ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u') {
         ++vowels
      }
   }
   return vowels; 
}

When you run the above Kotlin program, it will generate the following output:

Number of vowels in str1 : 6
Number of vowels in str2 : null

Extension Properties

Kotlin allows to define extension properties in very similar way like we defined extension function. Extension properties are also defined outside of the class. Since extensions do not actually insert members into classes, there is no efficient way for an extension property to have a backing field. This is why initializers are not allowed for extension properties.

We can add getter and setter along with the property which are nothing but the extension functions.

class Temperature(var celsius: Float)

fun main(args: Array<String>) {
   val t = Temperature(40f)
   println(t.fahrenheit)

   t.fahrenheit = 85f
   println(t.celsius)
}
var Temperature.fahrenheit: Float
    get() = (celsius * 9 / 5) + 32
    set(value) {
        celsius = (value - 32) * 5 / 9
    }

When you run the above Kotlin program, it will generate the following output:

104.0
29.444445

Quiz Time (Interview & Exams Preparation)

Answer : A

Explanation

Kotlin extension functions are defined outside the class without impacting existing functionality.

Advertisements