I'm trying to understand delegation and where it w...
# getting-started
k
I'm trying to understand delegation and where it would be useful. Suppose I have something like this:
Copy code
abstract class MyDelegate<T, U>(backingProperty: KProperty0<T>) : ReadOnlyProperty<Any?, U> {
  protected abstract val traits: Traits<U>
}
abstract class MyMutableDelegate<T, U>(backingProperty: KMutableProperty0<T>) : ReadWriteProperty<Any?, U> {
  protected abstract val traits: Traits<U>
}

abstract class MyIntDelegate<T>(backingProperty: KProperty0<T>) : MyDelegate<T, Int>(backingProperty) {
  override val traits = ...
}
abstract class MyMutableIntDelegate<T>(backingProperty : KMutableProperty0<T>) : MyMutableDelegate<T, Int>(backingProperty) {
  override val traits = ...
}
Is there a way I can commission a new type that
MyIntDelegate
and
MyMutableIntDelegate
can extend that will supply
traits
in such a way that the logic will not be duplicated between the two classes? Or is the fact that
traits
is declared as
protected
throw things off?
s
Since I don't quite understand where you aim to go with your trait business, so I'll just answer on where delegation might be usefull. The most common use cases are already implemented in the std-lib: lazy, vetoable, observable, notNull. •
lazy
is for lazy initialisation (I wonder what stable values coming to java will have on
lazy
) •
vetoable
let's you block setting a property to certain values, e.g. if you want to garantee that a certain Int property should never be negative •
observable
let's your code react on a property value being changed •
notNull
is similar to lateinit, but there's a usecase, I currently don't remember 😅, where
lateinit
wasn't an option (prefer
lateinit
) Honestly, I think I only ever use
lazy
and maybe
notNull()
once (but it's a hazy memory). You could build your own Delegate to e.g. log whenever a value changes, but otherwise I'm out of ideas 🤷‍♂️