avatarGabriel Shanahan

Free AI web copilot to create summaries, insights and extended knowledge, download it at here

3069

Abstract

old.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2FyD-OlhTNo&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FyD-OlhTNo&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="0d75">You can see that this allows us to implement observable properties in a completely general way, which can then be applied to any property. Again, as with delegating interface implementations, <b>the “thing” that we delegate to must be an instance of some class</b> (in this case, we constructed it in place).</p><p id="9827">A couple of other things need to be unpacked here:</p><p id="d3f2">The delegate class provides the implementations for the getter (and possibly setter, see bellow) — as such, <b>the</b> <b>property that is being delegated must be synthetic</b> (no backing field). Any data persisting must happen in the delegate — in the example, we passed the initial value <code>mutableMapOf()</code> directly into the delegate, as opposed to assigning it.</p><p id="2acc">The delegate class does not need to implement any interface, only <code>operator getValue()</code> for getters and <code>operator setValue()</code> for setters (we'll discuss <a href="https://readmedium.com/operators-6625ca0b8a63">operators</a> in a future lesson):</p><ul><li><code>getValue</code> receives the property owner as the first parameter, and the <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.reflect/-k-property/"><code>KProperty</code><*></a> instance corresponding to the property as the second one. The <code>getValue</code> method must return a value of the type of the delegated property.</li><li><code>setValue</code> receives the same arguments as <code>getValue</code>, along with a third one, which is the value being set. It returns Unit.</li></ul><p id="6de9">As mentioned in the previous point, implementing an interface is not necessary. However, as a convenience, <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.properties/-read-only-property/"><code>ReadOnlyPrope</code>rty</a> and <a href="https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.properties/-read-write-property/"><code>ReadWritePrope</code>rty</a> are available as templates, so you don’t have to remember the signatures.</p><p id="8648">Here’s the same example, but for a <code>var</code> equivalent, where we also observe mutations and take advantage of <code>ReadWriteProperty</code>:</p> <figure id="2c59"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2F9-Qc8tHKR&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2F9-Qc8tHKR&amp;image=https%3A%2F%2Fplay.kotlinlang.org%2Fassets%2Fog-image.png&amp;key=a1

Options

9fcc184b9711e1b4764040d3dc5c07&type=text%2Fhtml&schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="26aa">As it turns out, a similar implementation is already <a href="https://kotlinlang.org/docs/delegated-properties.html#observable-properties">part of the standard library</a>.</p><p id="e005">Any property can be delegated, not just class properties:</p> <figure id="c441"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2FtBZwBsTUn&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FtBZwBsTUn&amp;image=https%3A%2F%2Fplay.kotlinlang.org%2Fassets%2Fog-image.png&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="dcd9">There’s more to be said about delegated properties, but we’ll leave that to the <a href="https://kotlinlang.org/docs/delegated-properties.html">docs</a>. I strongly recommend that you take a look at the <a href="https://kotlinlang.org/docs/delegated-properties.html#standard-delegates">standard delegates</a> — some of them are pretty cool, especially <a href="https://kotlinlang.org/docs/delegated-properties.html#lazy-properties">lazy</a> and <a href="https://kotlinlang.org/docs/delegated-properties.html#delegating-to-another-property">delegating to a different property</a>.</p><h1 id="e3fa">Exercises</h1> <figure id="a9e5"> <div> <div> <img class="ratio" src="http://placehold.it/16x9"> <iframe class="" src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fpl.kotl.in%2FwVBQtZSrS%3Ffrom%3D23%26to%3D60&amp;display_name=Kotlin+Playground&amp;url=https%3A%2F%2Fpl.kotl.in%2FwVBQtZSrS%3Ffrom%3D23%26to%3D60&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=kotl" allowfullscreen="" frameborder="0" height="300" width="800"> </div> </div> </figure></iframe></div></div></figure><p id="de5b">Go back to <a href="https://readmedium.com/delegating-interface-implementation-232ef49bb977">Delegating Interface Implementation</a>, jump to the <a href="https://readmedium.com/table-of-contents-c52573cfa291">Table of Contents</a>, or continue to <a href="https://readmedium.com/delegation-summary-90066aa1c21f">Delegation — Summary</a>.</p><figure id="8ecd"><img src="https://cdn-images-1.readmedium.com/v2/resize:fit:800/1*biBSB579iezsNvEQ_NMLBg.png"><figcaption><a href="https://www.etnetera.cz/prace-u-nas?utm_source=medium&amp;utm_medium=GabrielShanahan&amp;utm_campaign=KotlinPrimer&amp;utm_content=join-our-team&amp;utm_term=KotlinPrimer#pozice">Join me in Etnetera</a></figcaption></figure></article></body>

Delegated Properties

Delegation without the mystification, part 2 — introduction to delegating properties via getValue and setValue, ReadOnlyProperty and ReadWriteProperty. A quick mention of lazy, observable, and delegating to different properties.

— — — — — — — — — — — — — — —

THE CURRENT VERSION OF THIS ARTICLE IS PUBLISHED HERE.

— — — — — — — — — — — — — — —

Tags: #FUNDAMENTAL CONCEPT #EXERCISE

This article is part of the Kotlin Primer, an opinionated guide to the Kotlin language, which is indented to help facilitate Kotlin adoption inside Java-centric organizations. It was originally written as an organizational learning resource for Etnetera a.s. and I would like to express my sincere gratitude for their support.

It is recommended to read the Introduction before moving on. Check out the Table of Contents for all articles.

Delegation can also help with the repetition involved when defining properties and their getters and setters.

A good example is an observable property — a property where a callback should be called whenever it is accessed. Using only the tools we have talked about so far, we would implement this something like the following:

However, we can see that defining a getter in this fashion is a pattern in its own right, and we would like to extract it, and possibly reuse it.

This is precisely what delegated properties are for:

You can see that this allows us to implement observable properties in a completely general way, which can then be applied to any property. Again, as with delegating interface implementations, the “thing” that we delegate to must be an instance of some class (in this case, we constructed it in place).

A couple of other things need to be unpacked here:

The delegate class provides the implementations for the getter (and possibly setter, see bellow) — as such, the property that is being delegated must be synthetic (no backing field). Any data persisting must happen in the delegate — in the example, we passed the initial value mutableMapOf() directly into the delegate, as opposed to assigning it.

The delegate class does not need to implement any interface, only operator getValue() for getters and operator setValue() for setters (we'll discuss operators in a future lesson):

  • getValue receives the property owner as the first parameter, and the KProperty<*> instance corresponding to the property as the second one. The getValue method must return a value of the type of the delegated property.
  • setValue receives the same arguments as getValue, along with a third one, which is the value being set. It returns Unit.

As mentioned in the previous point, implementing an interface is not necessary. However, as a convenience, ReadOnlyProperty and ReadWriteProperty are available as templates, so you don’t have to remember the signatures.

Here’s the same example, but for a var equivalent, where we also observe mutations and take advantage of ReadWriteProperty:

As it turns out, a similar implementation is already part of the standard library.

Any property can be delegated, not just class properties:

There’s more to be said about delegated properties, but we’ll leave that to the docs. I strongly recommend that you take a look at the standard delegates — some of them are pretty cool, especially lazy and delegating to a different property.

Exercises

Go back to Delegating Interface Implementation, jump to the Table of Contents, or continue to Delegation — Summary.

Join me in Etnetera
Kotlin
Java
Programming
Object Oriented
Delegation
Recommended from ReadMedium