Open In App

Delegated Properties in Kotlin

Last Updated : 21 Jan, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

Delegation is defined as the granting of any authority or power to another person (Boss assigning tasks to its employees) to carry out different work. However, the person who delegated the work remains accountable for the outcome of the delegated work. In a similar manner, there are various types of properties in a programming language that we can implement manually every time we want to use them to delegate other code work and we can implement them once and for all and put into the library if continuously used in our program’s.

Classification

There are mainly 3 types of properties used for delegation:

1. Lazy Properties: Lazy is a lambda function that takes in property to implement input and return an instance of Lazy where T denotes the type of property being used to implement lazy property. By default, lazy is synchronized means the value is computed at first call and the same value will be returned on other calls as well, we can stop the synchronization using LazyThreadSafetyMode.PUBLICATION as a parameter to the lazy() function. 

Example:

Kotlin




// Defining an immutable variable in kotlin
val lazyValue: String by lazy
{
  // Printing to standard output
  println("GeeksforGeeks")
  "GeeksforGeeks"
}
 
fun main()
{
  // Printing Var lazyValue values to standardoutput
  println(lazyValue)
  println(lazyValue)
}


Output:

GeeksforGeeks
GeeksforGeeks
GeeksforGeeks

Explanation:

Here, the value is computed only in “println”, and println calls lazyValue and the value in println is printed as output and all the callbacks will see the same the value due to synchronization.

2. Observable Properties: It notifies the user about the changes made into the class using handler which contains information about changes taking place. It is used to get notified via callbacks whenever the property changes. It contains two arguments to initialize the object with, new property or value(the initial value) and handler which contains information about all the modifications we will make by assigning the input to the object (it contains a property to be assigned, old value, the new value assigned).

Example:

Kotlin




import kotlin.properties.Delegates
 
class Myself
{
  // Creating a Myself Class with String variable name
  var name: String by Delegates.observable("company name")
  {
    // default Previous value "company name"
    prop, old, new ->
    println("$old -> $new") // Old value is being
                             // assigned a new value
  }
}
 
fun main()
{
  // Assigning name variable default value
  val V1 = Myself()
   
  // Assigning name variable a new value "Previous to"
  V1.name = "Previous to"
   
  // Now again changing "Previous to " to "New Value" value
  V1.name = "New Value"
}


Output: 

company name -> Previous to
Previous to -> New Value

Explanation:
Here the observable properties take in two arguments, the initial value as “company name” and second the handler which we call every time we assign it to the property with three values as “property to be modified, the previous value and new value.

3. Vetoable: It allows us to modify the values when the argument input by the user(s) fulfills the specified condition, it can be used in place of observable properties if the user wants to intercept assignment. Vetoable is like Observable Properties with additional features to allows to modify and notify the values when the condition is met.

Example: 

Kotlin




var max: Int by Delegates.vetoable(0)
{
  // Defining variable max with vetoable default value as 0
  property, oldValue, newValue ->
  newValue > oldValue
}
 
// printing value of max valriable default zero
println(max)
 
// assigning new value to max variable
max = 10
 
// printing newly assigned value to max variable
println(max)
 
// assigning new value to max variable but it
// doesnot satisfy max condition
max = 5
 
println(max)


Output: 

0
10
10

Explanation:

Firstly the default value is printed and afterward, the new max value is assigned and the value was not changed when the above callback was invoked again due to failure to satisfy the property. When the callback returns true it means the value of the property is changed to a new value, else the new value is discarded and the property still contains its old(previous) value.

4. Storing Properties in a Map: This method is used to store properties in a map function and use them for dynamic applications. 

Example: 

Kotlin




class Myself(val map: Map<String, Any?>)
{
  // defining class Myself
  val my_name: String by map // Variable my_name
  val my_age: Int     by map // Variable my_age
}
 
// calling Myself class using map function and
// assigning value to my_name and my_age variables
fun main()
{
  val V1 = Myself(mapOf(
        "my_name" to "GeeksforGeeks",
        "my_age"  to 50))
   
  // Printing value of my_name variable
  println(V1.my_name)
   
  // Printing value of my_age variable
  println(V1.my_age) 
}


Output:

GeeksforGeeks
50

This works also for var’s properties if you use a Mutable Map instead of read-only Map

Explanation:
Here we created a Myself class, containing a map function, for accepting the input in form of string or any(int, float, string, etc) and storing them in my_name and my_age variables in map function inside myself class and we can use the map function dynamically inside any newly created class as well.
 



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads