Custom delegated properties let you control how a property's value is stored and retrieved. This helps you add special behavior when getting or setting a value.
Custom delegated properties in Kotlin
import kotlin.reflect.KProperty class MyDelegate { operator fun getValue(thisRef: Any?, property: KProperty<*>): Type { // return the property value } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Type) { // set the property value } } class MyClass { var myProperty: Type by MyDelegate() }
The delegate class must define getValue and setValue operator functions.
The by keyword connects the property to its delegate.
import kotlin.reflect.KProperty class StringDelegate { private var storedValue = "" operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return storedValue } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { storedValue = value.uppercase() } } class Example { var name: String by StringDelegate() }
import kotlin.reflect.KProperty class LoggingDelegate<T>(private var value: T) { operator fun getValue(thisRef: Any?, property: KProperty<*>): T { println("Getting value of '${property.name}': $value") return value } operator fun setValue(thisRef: Any?, property: KProperty<*>, newValue: T) { println("Setting value of '${property.name}' from $value to $newValue") value = newValue } } class User { var age: Int by LoggingDelegate(0) }
This program uses a custom delegate to store the name always in uppercase. When we set p.name to "kotlin", it stores "KOTLIN". Printing p.name shows the uppercase string.
import kotlin.reflect.KProperty class UppercaseDelegate { private var storedValue = "" operator fun getValue(thisRef: Any?, property: KProperty<*>): String { return storedValue } operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) { storedValue = value.uppercase() } } class Person { var name: String by UppercaseDelegate() } fun main() { val p = Person() p.name = "kotlin" println(p.name) // Should print uppercase version }
Delegated properties can be used with var (read-write) or val (read-only) properties. For val, only getValue is needed.
The thisRef parameter refers to the object that owns the property. It can be useful if the delegate needs context.
Delegates can be generic to work with any type.
Custom delegated properties let you add special behavior when getting or setting a property.
You create a delegate class with getValue and setValue operator functions.
Use the by keyword to connect a property to its delegate.
Practice
custom delegated properties in Kotlin?Solution
Step 1: Understand property delegation concept
Delegated properties let you customize how a property's value is handled behind the scenes.Step 2: Identify the purpose of custom delegation
Custom delegated properties specifically allow control over getting and setting property values.Final Answer:
To control how a property's value is stored and retrieved -> Option CQuick Check:
Custom delegation = control property access [OK]
- Confusing delegation with constructors
- Thinking delegation defines functions
- Mixing delegation with method overriding
Solution
Step 1: Recall Kotlin delegation syntax
Delegated properties use thebykeyword followed by a delegate instance.Step 2: Match correct syntax
val prop by Delegate()correctly declares a delegated property.Final Answer:
val prop by Delegate() -> Option BQuick Check:
Delegation uses 'by' keyword [OK]
- Using '=' instead of 'by' for delegation
- Incorrect delegate type declaration
- Missing parentheses for delegate constructor
class Delegate {
operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): String {
return "Hello from delegate"
}
}
class Example {
val message: String by Delegate()
}
fun main() {
val e = Example()
println(e.message)
}Solution
Step 1: Understand getValue operator
ThegetValuefunction returns the string "Hello from delegate" when the property is accessed.Step 2: Trace property access in main()
Accessinge.messagecallsgetValueand prints the returned string.Final Answer:
Hello from delegate -> Option AQuick Check:
Delegate getValue returns string [OK]
- Expecting default property value instead of delegate's
- Confusing getValue with setValue
- Assuming compilation error due to missing parameters
class Delegate {
operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): Int {
return 42
}
}
class Example {
var number: Int by Delegate()
}
fun main() {
val e = Example()
e.number = 10
println(e.number)
}Solution
Step 1: Check property mutability and delegation
The propertynumberisvar, so delegate must support both get and set.Step 2: Verify delegate methods
TheDelegateclass only definesgetValue, missingsetValueneeded forvar.Final Answer:
Delegate class lacks setValue operator function -> Option DQuick Check:
var needs getValue and setValue [OK]
- Forgetting setValue for var properties
- Assuming getValue return type must be String
- Thinking delegate must be interface
class LoggingDelegate<T>(var value: T) {
operator fun getValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>): T {
println("Getting value of ${property.name}")
return value
}
operator fun setValue(thisRef: Any?, property: kotlin.reflect.KProperty<*>, newValue: T) {
println("Setting value of ${property.name} to $newValue")
value = newValue
}
}
class Example {
var data: String by LoggingDelegate("initial")
}
fun main() {
val e = Example()
e.data = "new"
println(e.data)
}Solution
Step 1: Analyze delegate methods
The delegate definesgetValueandsetValuewith print statements logging property access.Step 2: Trace main function output
Settinge.data = "new"prints setting log, then printinge.datatriggers get log and prints value.Final Answer:
Logs on get and set, prints 'Setting value of data to new' then 'Getting value of data' and 'new' -> Option AQuick Check:
Delegate logs on get/set correctly [OK]
- Missing setValue causes no set logging
- Assuming delegate must be non-generic
- Forgetting to pass initial value to delegate
Ready to prove it?
Pass the test and this pattern moves unknown
