Delegating Variables and Properties
We'll cover the following...
In the examples so far, we focused on delegation at the class level. You may delegate get and set access to properties of objects and local variables too.
When you read a property or a local variable, internally Kotlin calls a getValue()
function. Likewise, when you update a property or a variable, it calls a setValue()
function. By providing as delegate an object with these two methods, you may intercept calls to read and write local variables and objects’ properties.
Delegating variables
You can intercept access, both read and write, to local variables and alter what is returned and where and how the data is stored. To illustrate this facility, let’s create a custom delegate to intercept access of String
variables.
Suppose we’re creating an application that takes users’ comments. The text they enter may be displayed to other users, and we definitely want to be polite. So let’s write a delegate that filters out an offensive word, like “stupid”.
Let’s look at a small script with no filtering:
var comment: String = "Some nice message"println(comment)comment = "This is stupid"println(comment)println("comment is of length: ${comment.length}")
Running this will produce the rude output, no surprise:
Some nice message
This is stupid
comment is of length: 14
Our objective is to replace the word “stupid” so when the string is printed it’s not as rude. For that, let’s create a class named PoliteString
that has getValue()
and setValue()
methods with special signatures:
package com.agiledeveloper.delegatesimport kotlin.reflect.KPropertyclass PoliteString(var content: String) {operator fun getValue(thisRef: Any?, property: KProperty<*>) =content.replace("stupid", "s*****")operator fun setValue(thisRef: Any, property: KProperty<*>, value: String) {content = value}}
The class PoliteString
is all set to act as a delegate. Kotlin doesn’t require any interface to be implemented, no ceremony—all it wants is the get method. If the delegate ...