Operator Overloading in Kotlin


What is kotlin Operator overloading ?

Operator overloading is providing new definition for the existing operators in kotlin, Operator Overloading is useful when you want to have custom operation on the kotlin Objects and data.

Overloading of Operators should be defined only when it make sense to use them.

Every operator kotlin has internal functions, so when you try to use normal operator, these operators will invoke respective functions.

Operator functions are defined using operator keyword in kotlin, for overloading a method we must define method with operator keyword.

Operator overloading not only useful with numbers and String data but also useful with classes and objects

Some languages don't allow operator overloading but some languages do.

  • Java doesn't allow Operator overloading at all
  • Scala allows overloading of all operators,
  • Kotlin allows operator overloading but not all operator can be overloaded


I have showcased the operators and their respective functions in below table

Variables in Kotlin

Operators and internal functions in kotlin

Operator Internal Method
a + ba.plus(b)
a - ba.minus(b)
a * ba.times(b)
a / ba.div(b)
a % ba.rem(b), a.mod(b) (deprecated)
a > ba.compareTo(b)
a++a.inc()
b--b.dec()
a == ba.equals(b)
a != b!a.equals(b)
a < ba.compareTo(b)
a >= ba.compareTo(b)
a <= ba.compareTo(b)
a[i]a.get(i)
a[i, j]a.get(i, j)
a[i] = ba.set(i, b)
a[i, j] = ba.set(i, j, b)
a in bb.contains(a)
a !in b!b.contains(a)
a..ba.rangeTo(b)

Any & Unit & Nothing

Overload Arithmetic operator

Rules about Overloading :

  • You cannot overload your own operator in kotlin but you can overload existing kotlin operators
  • Operator function must either be Member functions or extension functions
  • You have freedom to overload operator function which accepts only same kind of data into a operator which accepts different types, For example, adding a string and Integer using + sign
  • You can have different return type than the operands(the values before and after the operator)
  • The parameters inside functions signature must follow val keyword

Example for Overloading Operator in kotlin :

In below example, we will be overriding the + operator which internally invoke plus() method in kotlin.

To overload the + operator, you do not have to overload the + operator but you just need to overload the plus() method, so when user uses + operator, the call comes to plus() method.

Steps to overload the functions in kotlin :

  • Create a class called OverloadOperatorexample
  • Create plus() method with operator keyword
  • return the same class with parameters modifications, like addition and multiplication and subtraction
  • I have performed three operation in above step just to show case that using plus() (or any method) we can change the total behavior of the operator in kotlin
  • Not with + operator we call the operations but also with using the plus() method we can perform same operations
  • we have overload the + operator, now we can use the + along with assignment operator(aka compound operator) to get the same result as above.

fun main(args:Array<String>)
{
    var oo1 = OperatorOverloadExample(2, 3, 4)
    var oo2 = OperatorOverloadExample(2, 2, 2)
    // plus , multiple, subtract using plus operator
    var result = oo1+oo2
    // a value
    println(result.a)
    // b value
    println(result.b)
    // c value
    println(result.c)
	
	println("************Using plus()********")
	var resultUsingMethod = oo1.plus(oo2)
	// a value
    println(resultUsingMethod.a)
    // b value
    println(resultUsingMethod.b)
    // c value
    println(resultUsingMethod.c)
	
	println("@@@@@@@@@@Compound Operator@@@@@@@@@@@")
	oo1 += oo2
	// a value
    println(oo1.a)
    // b value
    println(oo1.b)
    // c value
    println(oo1.c)
}
class OperatorOverloadExample(val a:Int, val b:Int, val c:Int){
    operator fun plus(ooe : OperatorOverloadExample):OperatorOverloadExample{
        return OperatorOverloadExample(a+ooe.a, b*ooe.b, c-ooe.c)
    }
}		

Nullability in Kotlin

Overload Compound Assignment Operators

In above example, we have overload the + operator and also we used it with assignment operator, but sometime you might want to have separate operations when user user += plus with assignment operator.

When user user += operator, the operator internally calls the plusAssign() function.

Note: try to avoid writing the definitions for plus() and plusAssign() in same class, use different classes

When user overloads plus() and plusAssign() functions in same class and if user uses by calling their name(plus(), plusAssign()) instead of symbol like +, += the there is not problem even if both functions in same class.

Compiler show error if user uses +, += operator when plus() and plusAssign() functions in same class, so be aware of it.


fun main(args:Array<String>)
{
    println("@@@@@@@@@@Compound Operator@@@@@@@@@@@")
	oo1 += oo2
	// a value
    println(oo1.a)
    // b value
    println(oo1.b)
    // c value
    println(oo1.c)
}
class OperatorOverloadExample(val a:Int, val b:Int, val c:Int){
    operator fun plusAssign(ooe : OperatorOverloadExample):OperatorOverloadExample{
        return OperatorOverloadExample(a+ooe.a, b*ooe.b, c-ooe.c)
    }
}		

You may get error if you try to overload plus and plusAssign in same class.

error : Error:(17, 9) Kotlin: Assignment operators ambiguity:

public final operator fun plus(ooe: OperatorOverloadExample): Unit defined in OperatorOverloadExample

public final operator fun plusAssign(ooe: OperatorOverloadExample): Unit defined in OperatorOverloadExample

Below example s only for showcasing the error purpose,


fun main(args:Array<String>)
{
    var oo1 = OperatorOverloadExample(2, 3, 4)
    var oo2 = OperatorOverloadExample(2, 2, 2)
    // just to call
    var result = oo1+oo2
    // show error
    oo1 += oo2;
}
class OperatorOverloadExample(val a:Int, val b:Int, val c:Int){
    operator fun plus(ooe : OperatorOverloadExample){
    }
    operator fun plusAssign(ooe : OperatorOverloadExample){
    }
}		

Re-write the main bloc in above code like below to remove error, but i recommend not to overload the plus() and its respective compound operator in same class, it is applicable for all compound operators.


fun main(args:Array<String>)
{
    var oo1 = OperatorOverloadExample(2, 3, 4)
    var oo2 = OperatorOverloadExample(2, 2, 2)
    // just to call
    var result = oo1.plus(oo2)
    // show error
    oo1.plusAssign(oo2)
}		

Overload Unary Operators in kotlin

Unary operator overloading is also similar to the overloading of arithmetic operator, add the operator overload functions as Member or as Extension function and mark the function with operator keyword

Unary Operator functions should not take any parameters

below example I have showcased unaryMinus(-) and the dec(--) functions, Normally dec functions decrements the value by 1 but here we are decrementing by 3.


fun main(args:Array<String>)
{
    var oo1 = OperatorOverloadExample(5, 9, 21)
    // unary minus
    var result = -oo1
    println(result.a)
    println(result.b)
    println(result.c)
    // using decrement operator
    oo1--
    println(oo1.a)
    println(oo1.b)
    println(oo1.c)
}
class OperatorOverloadExample(val a:Int, val b:Int, val c:Int){
    operator fun unaryMinus():OperatorOverloadExample{
        return OperatorOverloadExample(-a, -b, -c)
    }
    operator fun dec():OperatorOverloadExample{
        return OperatorOverloadExample(a-3, b-3, c-3)
    }
}		

infix functions in Kotlin

Comparison Operator Overloading in kotlin

Comparison operator compares two values, we can overload the comparison operator either by overloading CompareTo() or equals method, both these two methods are part of Any Class.

Important : equals method and CompareTo functions are already overloaded in Any class, so we cannot overload them in our class. But if you want to provide new meaning for these methods, then you must override them (as overloading is prohibited)

Let's learn about overriding the equals method in kotlin, equals functions compares two objects and verifies whether both are same or not. Here, the equals method is invoked by "==" operator and you cannot override the "===" operator

Equals function should return Boolean value as a result, so here you will be able to judge what is higher(larger) or lesser(smaller)


import java.awt.Point
fun main(args:Array<String>)
{
    // both are diffrent
    println(EqualsOperator(10,20) == EqualsOperator(10,21))
    // both point at same address
    println(EqualsOperator(10,20) == EqualsOperator(10,20))
    // you cannot compare diffrent type,
    // kotlin compiler is intelligent enough to say
    // you cannot compare different types
    // but you are free to un-comment below and use
    /*println(EqualsOperator(10,20) == Point(10,20))*/
}
class EqualsOperator(val a:Int, val b:Int){
    override fun equals(obj:Any?):Boolean{
        println("comparing values by custom equals")
        // check for the type, if it is not same type then both are different
        if(obj !is EqualsOperator){
            return false
        }
        // compare whether both point to same address
        if(obj === this){
            return true
        }
        // if not same object(at address) at least compare values
        return a == obj.a && b == obj.b
    }
}		

Actually you cannot overload the logic of the CompareTo() function, but you can override the method just like equals.

CompareTo() function results in Int value like below

  • value1 > value2 : if value1 is greater than value2 then > operator returns true, calls a.compareTo(b) > 0
  • value1 < value2 : if value1 is less than value2 then < operator returns true, calls a.compareTo(b) < 0
  • value1 >= value2 : if value1 is greater than or equal to value2 then >= operator returns true, calls a.compareTo(b) >= 0
  • value1 <= value2 : if value1 is lesser than or equal to value2 then <= operator returns true, calls a.compareTo(b) <= 0
  • value1 == value2 : value1 is equal to value2
    When using compareTo you have to override the method in the comparable interface
  • To Indicate a is less than b, it returns a negative integer
  • When b is greater than a, it returns positive integer
  • For equality, it return 0
Let's override the CompareTo() function with help of compareValuesBy functions

fun main(args:Array<String>)
{
    // both are diffrent
    println(EqualsOperator(10,20).compareTo(EqualsOperator(10,21)))
    // both are same
    println(EqualsOperator(10,20).compareTo(EqualsOperator(10,20)))
    // both are diffrent
    println(EqualsOperator(10,21).compareTo(EqualsOperator(10,20)))
    // use relational operators to get whether true or false values
    // both are diffrent
    println(EqualsOperator(10,20) > EqualsOperator(10,21))
    // bot are same values
    println(EqualsOperator(10,20) < EqualsOperator(10,20))
    // both are diffrent
    println(EqualsOperator(10,21) >= EqualsOperator(10,20))
}
class EqualsOperator(val a:Int, val b:Int): Comparable<EqualsOperator>{
    override fun compareTo(obj:EqualsOperator):Int{
        return compareValuesBy(this, obj,
                EqualsOperator::a, EqualsOperator::b)
    }
}		

Explanation:

: Comparable<EqualsOperator> We are extending the Comparable with type of EqualsOperator

compareValuesBy(this, obj, EqualsOperator::a, EqualsOperator::b) we are telling the functions what are to compare, like compare a, b from this object and obj Object

kotlin lambdas with receivers

Things to remember in Operator Overloading

  • Operator overloading cannot change the precedence and associatively of operators. However, if you want to change the order of evaluation, parenthesis should be used.
  • Operator overloading is useful in that you can write 1 line of code instead of having to write many more lines of codes that do the same thing.
  • Perform Operator overloading if it is easing the problem otherwise don't overload it

aaaaaaaaaaaaa
Comment / Suggestion Section
Point our Mistakes and Post Your Suggestions

Recent Addition

new tutorial Selenium Online Training : Our next online training course for Selenium with Java starts from 17th December 2018.

You can attend first 3 classes for free, the total course fee is INR 10,000

The course time would be 8.00 PM(IST) for the first three classes

If you are interested to learn, then you can join the course by sending email to chercher.tech@gmail.com

or Register below


 
Join My Facebook Group
Join Group