# Extension functions

With the help of *extension functions* classes can be “extended”, even if they are actually `final`

- like `String`

, for example.

Extension functions allow you to declare functions outside of a class, and yet their call looks like that of a *method* of that given class.

## Example

Suppose that in a project it is often necessary to calculate the *square of an integer*.

A suitable function for this is a quick write:

```
fun squared(i: Int) : Int {
return i * i
}
```

or, thanks to Kotlin’s *expression bodies*, even shorter:

`fun squared(i: int) `__= i * i__

Since Kotlin allows functions on package level, you could easily use this function now - without any utility class.

But with Kotlin we can do even better!

Using a corresponding *extension function*, we can “teach” the `Int`

class itself to compute and return the square of an integer.

This means that calling the `squared`

method looks a lot more “object oriented”, and the function “moves even closer to the subject”:

```
val i = 42.squared()
```

With Java that would not be possible like that - and looks accordingly unfamiliar.

Let’s take a look at the `squared`

extension function that makes this possible:

```
fun Int.squared() = this * this // extension function
val i = 42.squared() // call the Extension Function
check(i == 42 * 42) // proof that everything works correctly
```

The declaration of the `squared`

function actually looks quite usual - if it were not for the `Int.`

in its name.
Also, it suddenly does not take an integer for an argument anymore…?

Let’s start with the unfamiliar prefix.
This is called the *receiver type* and specifies the *type* we want to *extend* - `Int`

in our case - followed by a `.`

.

The function itself now lacks the argument `i`

, so we can no longer calculate `i * i`

.
Instead, we use `this`

.
But how is this possible given the function is not even noted within a class’s body?

Well, that’s exactly what we have previously specified the *receiver type* (`Int`

) for.
It is the representative of a class that would otherwise surround the function.

So if we call the function - `val i = 42.squared()`

- the instance to which we call it (`42`

) becomes `this`

, which is referenced within the function.

In fact, an extension function behaves very similar to one that is directly noted in a class itself - and looks almost exactly the same. There is one very important difference though:

Within an extension function you can not access `private`

or `protected`

properties of a class!

Thus, the essential difference between inheritance and extension remains: while inheritance is (hopefully) intended by the developer of the parent class, but at least considered, with extension functions you can safely extend any class - meaningfully limited to no wreak havoc.

## Extension properties

Besides extension *functions* there also are extension *properties*.

So we can improve our example a little by declaring the following *extension property* instead of the *extension function*:

```
val Int.squared get() = this * this
```

Again, the declaration of the property differs from its “normal” counterpart only by the prefix of the receiver type.

Thus, the call is still a bit nicer, since the empty parentheses are omitted:

```
val s = 42.squared
```

As with common properties and functions, it is largely a matter of taste (=style guide), whether one uses a function or property.

In that case, I would personally prefer the property - simply because I would consider the square of a number quite one of its properties, its calculation is not really expensive and - last but not least - the call seems more elegant without parentheses.

## Summary

- Extension functions allow functions to be declared and called as if they were an integral part of the receiver type.
- To declare an extension function, precede its name with the name of the type you want to extend (“receiver type”), separated by a
`.`

character. - To reference the actual instance of the receiver type,
`this`

is used. - Extension functions are common functions in every other aspect - particularly they have no access to
`protected`

and`private`

properties of the*receiver type*.