# Lesson 42 – Overloading operators in Kotlin Programming Language

##### Share this

The Kotlin language allows certain operators to be overloaded and to act in different ways according to the object that is applied.

Operator overloading should be used as long as it makes sense for the class being deployed. Mathematical concepts of vectors and matrices are cases where the overload of operators can make our code more readable and elegant.

To overload the +, -, * and / operators we must implement a series of special methods within the class:

Operation Name of the method to be defined A + b plus A - b minus A * b times A / b div A% b rem A..b rangeTo

**Problem 1**

Declare a class named Vector that manages an array of 5 integer elements and loads random values between 1 and 10. Overloading the +, -, * and / or operators

In the main define a series of objects of the Vector class and operate with them

**Project162 **

```
class Vector {
val array = IntArray (5)
fun load () {
for (i in array.indices)
array [i] = (Math.random () * 11 + 1) .toInt ()
}
// www.coding180.com
fun print () {
for (element in array)
print ("$element")
println ()
}
operator fun plus (vector2: Vector): Vector {
var sum = Vector ()
for (i in array.indices)
sum.array [i] = array [i] + vector2.array [i]
return sum
}
operator fun minus (vector2: Vector): Vector {
var subtract = Vector ()
for (i in array.indices)
subtract.array[i] = array [i] - vector2.array [i]
return subtract
}
operator fun times (vector2: Vector): Vector {
var product = Vector ()
for (i in array.indices)
product.array [i] = array [i] * vector2.array [i]
return product
}
operator fun div (vector2: Vector): Vector {
var division = Vector ()
for (i in array.indices)
division.array [i] = array [i] / vector2.array [i]
return division
}
}
fun main (args: Array <String>) {
val vec1 = Vector ()
vec1.load ()
val vec2 = Vector ()
vec2.load ()
vec1.print ()
vec2.print ()
val vecSum = vec1 + vec2
println ("Sum component to component of the two vectors")
vecSum.print()
val vecSub = vec1 - vec2
println ("The component-to-component subtraction of the two vectors")
vecSub.print ()
val vecProduct = vec1 * vec2
println ("The product component to component of the two vectors")
vecProduct.print ()
val vecDivision = vec1 / vec2
println ("The component-to-component division of the two vectors")
vecDivision.print ()
}
```

To overload the + operator we must implement the plus method that receives a single parameter, in this case of type Vector and returns another object of the Vector class.

We must precede the keyword fun with the keyword operator.

Within the method we create an object of class ** Vector **and proceed to initialize its property array with the sum component to component of the two arrangements of each object:

Operator fun plus (vector2: Vector): Vector { Var sum = Vector () For (i in array.indices) Sum.array [i] = array [i] + vector2.array [i] Return sum }

To call this method in the main we use the + operator:

Val vecSum = vec1 + vec2

The other syntax that we can use is the one already known to invoke the method:

Val vecSum = vec1.plus (vec2)

With this, we can verify that the program is more readable using the + operator.

Let’s think that if we have to add 4 vectors the syntax would be:

Val vecSum = vec1 + vec2 + vec3 + vec4

In complex algorithms, our code can greatly simplify the correct use of operator overload.

We can overload an operator with objects of different kinds.

**Problem 2**

Declare a class named **Vector** that manages an array of 5 integer elements and loads random values between 1 and 10. Overloading the * operator to multiply a Vector with an integer (multiply each component of the array by the integer)

**Project163**

```
class Vector {
val array = IntArray (5)
// www.coding180.com
fun load () {
for (i in array.indices)
array [i] = (Math.random () * 11 + 1) .toInt ()
}
fun print () {
for (element in array)
print ("$element")
println ()
}
operator fun times (value: Int): Vector {
var sum = Vector ()
for (i in array.indices)
sum.array [i] = array [i] * value
return sum
}
}
fun main (args: Array <String>) {
val vec1 = Vector ()
vec1.load ()
vec1.print ()
println ("The product of a vector with the number 10 is")
val vecProductoEnt = vec1 * 10
vecProductoEnt.print ()
}
```

In this problem to overload the * operator of a Vector by an integer type to the method must arrive an int data type:

Operator fun times (value: Int): Vector { Var sum = Vector () For (i in array.indices) Sum.array [i] = array [i] * value Return sum }

In the main function when we multiply an object of the class Vector by a data type **Int** we must do it in this order:

Println ("The product of a vector with the number 10 is") Val vecProductoEnt = vec1 * 10 VecProductEnt.print ()

If we inverse the product, i.e an Int by a Vector, we must define the ** times **method in the Int class. The complete program would then be:

```
class Vector {
val array = IntArray (5)
fun load () {
for (i in array.indices)
array [i] = (Math.random () * 11 + 1) .toInt ()
}
fun print () {
for (element in array)
print ("$element")
println ()
}
operator fun times (value: Int): Vector {
var sum = Vector ()
for (i in array.indices)
sum.array [i] = array [i] * value
return sum
}
}
operator fun Int.times (vec: Vector): Vector {
var sum = Vector ()
for (i in vec.array.indices)
sum.array [i] = vec.array [i] * this
return sum
}
fun main (args: Array <String>) {
val vec1 = Vector ()
vec1.load ()
vec1.print ()
// www.coding180.com
println ("The product of a vector with the number 10 is")
val vecProductoEnt = 10 * vec1
vecProductoEnt.print ()
println ("The product of an integer 5 by a vector is")
val vecProductoEnt2 = vec1 * 5
vecProductoEnt2.print ()
}
```

We use the concept of extension functions that we saw earlier:

Operator fun Int.times (vec: Vector): Vector { Var sum = Vector () For (i in vec.array.indices) Sum.array [i] = vec.array [i] * this Return sum }

**Problem 3**

Declare a class named ** Vector **that manages an array of 5 integer elements and loads random values between 1 and 10. Overloading the ++ and – operators (you must increase or decrease each element of the array by one)

**Project 164**

```
class Vector {
val array = IntArray (5)
// www.coding180.com
fun load () {
for (i in array.indices)
array [i] = (Math.random () * 11 + 1) .toInt ()
}
fun print () {
for (element in array)
print ("$element")
println()
}
operator fun inc (): Vector {
var sum1 = Vector ()
for (i in array.indices)
sum1.array [i] = array [i] + 1
return sum1
}
operator fun dec (): Vector {
var remains1 = Vector ()
for (i in array.indices)
remains1.array [i] = array [i] - 1
return remains1
}
}
fun main (args: Array <String>) {
var vec1 = Vector ()
vec1.load ()
println ("Original Vector")
vec1.print ()
vec1 ++
println ("After calling operator ++")
vec1.print ()
vec1--
println ("After calling the operator -")
vec1.print ()
}
```

When we want to overload the operators ++ and – we must implement the methods ** inc** and

*. These methods do not receive any parameters and return objects of the*

**dec****class by increasing by one or decreasing by one each component of the array:**

*Vector*Operator fun inc (): Vector { Var sum1 = Vector () For (i in array.indices) Sum1.array [i] = array [i] + 1 Return sum1 } Operator fun dec (): Vector { Var remains1 = Vector () For (i in array.indices) remains1.array [i] = array [i] - 1 Return remains1 }

When we call the operators ++ and – the object that returns is assigned to the variable by which we call, this makes it necessary to define the object of the class ** Vector **with the keyword

*:*

**var**Var vec1 = Vector () Vec1.load () Println ("Original Vector") Vec1.print ()

Once the operator ++ is called:

Vec1 ++

Now * vec1 *has the reference to the object that was created in the method

*:*

**inc**Println ("After calling operator ++") Vec1.print ()

No changes need to be made if we need to use prefix notation with ++ and – operators:

++ vec1 --vec1

### Overloading operators>> = y <<=

To overload these operators we must implement the * compareTo* method.

**Problem 4**

Implement a class called ** Person **that will have properties like their

*name*and

*age*. Overload the operators >> = and <<=.

**Project165**

```
class Person (val name: String, val age: Int) {
fun print () {
println ("Name: $name and has an age of $age")
}
// www.coding180.com
operator fun compareTo (per2: Person): Int {
return when {
age < per2.age -> -1
age > per2.age -> 1
else -> 0
}
}
}
fun main (parameter: Array <String>) {
val person1 = Person ("Juan", 30)
person1.print()
val person2 = Person ("Ana", 30)
person2.print ()
println ("Elderly person")
when {
person1> person2 -> person1.print ()
person1 <person2 -> person2.print ()
else -> println ("They are the same age")
}
}
```

The * compareTo *method must return an

*Int*, indicating that if it returns a 0 the two people are the same age. If you return 1, the person to the left of the operator is of legal age and vice versa:

Operator fun compareTo (per2: Person): Int { Return when { Age <per2.age-> -1 Age> per2.age -> 1 Else -> 0 } }

Then we can ask with these operators for objects of the class ** Person **which has a greater age:

When { Person1 > person2 -> person1.print () Person1 < person2 -> person2.print () Else -> println ("They are the same age") }

### Overload of subscripts operators

In Kotlin we can overload the handling of subscripts by implementing the *get* and *set* methods.

The expression translates A [i] = b a.set (i, b) A [i, j] = b a.set (i, j, b) A [i_1, ..., i_n] = b a.set (i_1, ..., i_n, b) To [i] a.get (i) A [i, j] a.get (i, j) To [i_1, ..., i_n] a.get (i_1, ..., i_n)

**Problem 5**

Implement a * TaTeTi *class that defines a property for the board that is an

**of 9 elements with a zero value.**

*IntArray*There are two players who have chips, the first player loads the 1 and the second one loads a 2.

By means of

*subscripting*operators, overload allow assigning the chips to each position of the board by means of two subscripts that indicate the row and column of the board.

**Project166**

```
class TaTeTi {
val table = IntArray (9)
// www.coding180.com
fun print () {
for (row in 0..2) {
for (column in 0..2)
print ("${this [row, column]}")
println ()
}
println ()
}
operator fun set (row: Int, column: Int, value: Int) {
table[row * 3 + column] = value
print()
}
operator fun get (row: Int, column: Int): Int {
return table [row * 3 + column]
}
}
fun main (args: Array <String>) {
val game = TaTeTi ()
game [0, 0] = 1
game [0, 2] = 2
game [2, 0] = 1
game [1, 2] = 2
game [1, 0] = 1
}
```

The Table property stores the nine boxes of the * game *in an array. In order to be more intuitive the loading of chips in the game of tateti, we proceed to overload the operator of subscripts with row and column.

The idea is that we can indicate a row, column and the tab that is loaded with the syntax:

Game [0, 0] = 1 Game [0, 2] = 2 Game [2, 0] = 1 Game [1, 2] = 2 Game [1, 0] = 1

Each assignment actually calls the set method, which in addition to loading the tab goes to print the board:

Operator fun set (row: Int, column: Int, value: Int) { table[row * 3 + column] = value to print() }

The board impression proceeds to access the overload of the subscript operator by accessing the get method:

Fun print () { For (row in 0..2) { For (column in 0..2) Print ("$ {this [row, column]}") Println () } Println () }

The overload to retrieve the stored value is done by implementing the get method:

Operator fun get (row: Int, column: Int): Int { Return table[row * 3 + column] }

Remember that the overload of operators aims to make our program more readable, here we succeed because it is very easy to understand how we load the chips on the board with the assignment:

Val game = TaTeTi () Game [0, 0] = 1

Let’s always keep in mind that when an operator is overloaded it is actually calling a class method.

The execution of this program shows us on the screen the successive states of the Tateti table as we assign pieces to it:

### Parenthesis Overload

In Kotlin we can also overload the parentheses by implementing the invoke method.

The expression translates To () a.invoke () To (i) a.invoke (i) To (i, j) a.invoke (i, j) To (i_1, ..., i_n) a.invoke (i_1, ..., i_n)

**Problem 6**

Raise a class Data that manages 10 data values in an array of type IntArray.

Overload the parentheses operator for the class and access by a position the value of a specific data.

**Project167 **

```
class Data {
val array = IntArray (10)
fun withdraw () {
for (i in array.indices)
array [i] = ((Math.random () * 6) + 1) .toInt ()
}
operator fun invoke (nro: Int) = array [nro]
}
fun main (args: Array <String>) {
var data = Data ()
data.withdraw ()
println (data (0))
println (data (1))
for (i in 2..9)
println (data (i))
}
```

We declare an array of 10 integers and store random values between 1 and 6:

Class Data () { Val array = IntArray (10) Fun withdraw () { For (i in array.indices) Array [i] = ((Math.random () * 6) + 1) .toInt () }

In the main function we create the object of the Data class and call the ** withdraw ** method:

Var data = Data () Data.withdraw()

Then if we have the name of the object and in parentheses, we pass an integer will call the method invoke and will return in this case an integer that represents the value of the die for that position:

Println (data (0)) Println (data (1)) For (i in 2..9) Println (data (i))

In the Data class we specify the overhead of the parentheses operator with the implementation of the invoke method:

Operator fun invoke (nro: Int) = array [nro]

For this problem, we could also have overloaded the bracket operator as we saw earlier.

The choice of which operator to overload depends on the problem to be developed and to see which is clearer its use.

### Overload of operators + = – = * = / =% =

The methods invoked for these operators are:

The expression translates A + = b a.plusAssign (b) A - = b a.minusAssign (b) A * = b a.timesAssign (b) A / = b a.divAssign (b) A% = b a.modAssign (b)

**Problem 7**

Declare a class called * Vector *that manages an array of 5 integer elements.

Overload the operator + =

In the main define a series of objects of the class and use the operator + =

**Project168**

```
class Vector {
val array = IntArray (5, {it})
fun print () {
for (element in array)
print ("$element")
println ()
}
operator fun plusAssign (vec2: Vector) {
for (i in array.indices)
array[i] += vec2.array [i]
}
}
fun main (args: Array <String>) {
val vec1 = Vector ()
vec1.print ()
val vec2 = Vector ()
vec2.print ()
vec1 += vec2
vec1.print ()
}
```

To overload the + = operator in the Vector class we define the ** plusAssign **method:

Operator fun plusAssign (vec2: Vector) { For (i in array.indices) Array[i] + = vec2.array [i] }

The method reaches an object of the class Vector that serves to access the array contained in it.

In the main function we define two objects of class *Vector* and proceed to accumulate in *vec1* the contents of *vec2* by the + = operator:

Fun main (args: Array <String>) { Val vec1 = Vector () Vec1.print () Val vec2 = Vector () Vec2.print () Vec1 + = vec2 Vec1.print () }

### Overload of operators in y! In

The methods invoked for these operators are:

The expression translates A in b b.contains (a) A! In b! B.contains (a)

**Problem 8**

Raise a data class ** Student **to store their document

*number*and

*name*.

Then in a

*class define an Array with 3 objects of the*

**Course***class. Overload the in operator to verify if a document number is enrolled in the course.*

**Student****Project169**

```
data class Student (val document: Int, val name: String)
// www.coding180.com
class Course {
val students = arrayOf (Student (123456, "Mark"),
Student (666666, "Ana"),
Student (777777, "Luis"))
operator fun contains (document: Int): Boolean {
return students.any {document == it.document}
}
}
fun main (args: Array <String>) {
val course1 = Course ()
if (123456 in course1)
println ("Student Marcos is enrolled in the contract")
else
println ("Marcos student is not enrolled in the contract")
}
```

We declare a data class that represents a *Student*:

Data class Student (val document: Int, val name: String)

We declare the class Courses defining an Array with four students:

Class Course { Val students = arrayOf (Student (123456, "Marcos"), Student (666666, "Ana"), Student (777777, "Luis"))

We overloaded the operator in:

Operator fun contains (document: Int): Boolean { Return students.any {document == it.documento} }

The method returns an integer representing the document number to be searched within the student array. In the case that we find a true return, in the negative case, we return a false.

We can write more concisely the contains method:

Operator fun contains (document: Int) = students.any {document == it.document}

In the main, we create an object of the class ** course **and then through the operator in we can verify if a certain number of

*is registered in the course of students:*

**document**Fun main (args: Array <String>) { Val course1 = Course () If (123456 in course1) Println ("Student Marcos is enrolled in the contract") Else Println ("Marcos student is not enrolled in the contract") }

## Comments

## Leave a Comment