Built-in delegates

Aside from user-defined delegates, the Kotlin library also provides some useful built-in delegates that can be used in our applications. One of these delegates is the observable delegate, which triggers when a value is assigned to the property. 

The observable takes the following parameters:

  • The first parameter is the initial value of the property
  • The second parameter is a lambda expression that takes the property type, the old value, the new value, and the body of the lambda expression

The following example shows the observable delegate with the age and name properties of the Person class. This delegate observes the properties and is triggered every time the value of the property changes:

class Person {
var age : Int by Delegates.observable(0) { property, oldValue, newValue ->
println("oldValue $oldValue newValue $newValue")
}

var name : String by Delegates.observable("Default"){property, oldValue, newValue -> shock(oldValue,newValue) }

fun shock(old: String, new: String){
println("Old name $old and New name $new")
}
}

fun main(args: Array<String>) {
val person = Person()
person.age = 40
person.name = "Abid"
person.name = "Khan"
}

Notice that the  age property is assigned with 0 and the lambda expression holds both the new and the old values:

oldValue 0 newValue 40
Old name Default and New name Abid
Old name Abid and New name Khan

In the Class properties section, we learned how to protect the properties from an invalid input:

var age : Int = 1
get() = field
set(update) {
if(update > 0)
field = update
}

Before updating the age property, verify whether the provided value is negative. To do this, Kotlin provides the vetoable delegate. Let's see how it works:

class Person {
var name : String by Delegates.vetoable("Default",{property, oldValue, newValue -> newValue.isNotEmpty()})

var age : Int by Delegates.vetoable(1 ,{property, oldValue, newValue -> newValue > 0})
}

In the Person class, we implement vetoable for both properties. The vetoable delegate takes the following parameters:

  • The first parameter is the initial value of the property
  • The second parameter is a lambda expression that takes the property type, the old value, the new value, and the body of the lambda expression

We can apply our logic in the lambda expression. For the name property, we implement logic that ensures we retain the value in the name property if the new property is empty. For the age property, we implement logic that ensures we don't update the age property if the new value is negative:

 fun main(args: Array<String>) {
val p = Person()
p.name = "Bob"
println(p.name)
p.name = ""
println(p.name)

p.age = 10
println(p.age)
p.age = -6
println(p.age)
}

We can verify this code by assigning both valid and invalid values.

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

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