Operator overloading

Hold on a second, how do square brackets keep working when we extended a map? Aren't they some kind of magic? 

Well, actually no. No magic there. As you may have guessed by the title of this section, Kotlin supports operator overloading. Operator overloading means that the same operator acts differently, depending on the type of arguments it receives. 

If you've ever worked with Java, you're familiar with operator overloading already. Think of how the plus operator works. Let take a look at the example given here:

System.out.println(1 + 1); // 2
System.out.println("1" + "1") // 11

Based on whether two arguments are either strings or integers, the + sign acts differently. 

But, in the Java world, this is something that only the language itself is allowed to do. The following code won't compile, no matter how hard we try:

List<String> a = Arrays.asList("a");
List<String> b = Collections.singletonList("b"); // Same for one argument
List<String> c = a + b;
In Java 9, there's also List.of(), which serves a similar purpose to Arrays.asList().

In Kotlin, the same code prints [a, b]:

val a = listOf("a")
val b = listOf("b")
println(a + b)

Well, that makes a lot of sense, but maybe it's just a language feature:

data class Json(val j: String)
val j1 = Json("""{"a": "b"}""")
val j2 = Json("""{"c": "d"}""")
println(j1 + j2) // Compilation error!

Told you it was magic! You cannot simply join two arbitrary classes together.

But wait. What if we create an extension function for our Json class, plus(), as follows:

operator fun Json.plus(j2: Json): Json {
// Code comes here
}

Everything but the first keyword, operator, should look familiar to you. We extend the Json object with a new function that gets another Json and returns Json.

We implement the function body like this:

val jsonFields = this.j.split(":") + j2.j.split(":")
val s = (jsonFields).joinToString(":")
return Json ("""{$s}""")

This isn't really joining any JSON, but it joins Json in our example. We take values from our Json, values from the other Json, then join them together and put some curly brackets around them.

Now look at this line:

println(j1 + j2)

The preceding code prints the following output:

{{"a": "b"}:{"c": "d"}}

Actually, it will print: Json(j={{"a": "b"}:{"c": "d"}}). This is because we didn't override the toString() method in our example for brevity.

So, what's this operator keyword about?

Unlike some other languages, you cannot override every operator that exists in Kotlin languages, just a chosen few.

Albeit limited, the list of all operators that can be overridden is quite long, so we'll not list it here. You can refer to it in the official documentation: 
https://kotlinlang.org/docs/reference/operator-overloading.html.

Try renaming your extension method to:

  • prus(): Just a name with a typo
  • minus(): The existing function that correlates with the - sign

You will see that your code stops compiling. 

The square brackets that we started with are called indexed access operators and correlate to the get(x) and set(x, y) methods.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.30.62