Is there any possibility to pass this
when delegating class in kotlin?
class SomeFlow : Flow, SmsAuthentication by DefaultSmsAuthentication(this)
It says this
does not exist in this context. The other class looks like this:
class DefaultSmsAuthentication(val flow: Flow) : SmsAuthentication
Kotlin supports “delegation” design pattern by introducing a new keyword “by”. Using this keyword or delegation methodology, Kotlin allows the derived class to access all the implemented public methods of an interface through a specific object.
You can create delegates as anonymous objects without creating new classes, by using the interfaces ReadOnlyProperty and ReadWriteProperty from the Kotlin standard library. They provide the required methods: getValue() is declared in ReadOnlyProperty ; ReadWriteProperty extends it and adds setValue() .
The primary advantage of delegation is run-time flexibility – the delegate can easily be changed at run-time. But unlike inheritance, delegation is not directly supported by most popular object-oriented languages, and it doesn't facilitate dynamic polymorphism.
Simply put, delegated properties are not backed by a class field and delegate getting and setting to another piece of code. This allows for delegated functionality to be abstracted out and shared between multiple similar properties – e.g. storing property values in a map instead of separate fields.
How about injecting this
by setter, not by constructor
?
For example:
interface SmsAuthentication {
fun withFlow(flow: Flow)
fun auth()
}
class DefaultSmsAuthentication() : SmsAuthentication {
var flow: Flow? = null
override fun withFlow(flow: Flow) {
this.flow = flow
}
override fun auth() {
flow?.proceed()
}
}
class SomeFlow : Flow, SmsAuthentication by DefaultSmsAuthentication() {
init {
withFlow(this)
}
}
However, you need to call withFlow()
in constructor
by hand every time. You may forget to call it.
You may want to have SmsAuthentication
as a property. So you just inject it by lazy
and call it in need. I think it's safer way.
class SomeFlow : Flow, SmsAuthentication {
val auth by lazy { DefaultSmsAuthentication(this) }
override fun auth() {
auth.auth()
}
}
You can also apply Decorator pattern, conversely:
class DefaultSmsAuthenticationFlow(val flow: Flow) :
SmsAuthentication,
Flow by flow
{
override fun auth() {
// you can use flow as this here
}
}
fun doAuth(flow: Flow) {
DefaultSmsAuthenticationFlow(flow).auth()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With