This is the 14th day of my participation in Gwen Challenge
Kotlin commissioned
As for the introduction of delegation, I will use my own implementation of a number of examples of the most common implementation of several ways to explain delegation, the description will be very clear and easy to understand.
In particular, the Lazy initialization method of the ViewModel extension library in Android will be simulated to help you understand better
Use delegates to implement inheritance
Delegate using the by keyword
- Code instructions
When the BrokenTaxi drive method is called, the method call is forwarded to the drive method of Taxi passed in by the parameter
The compiler uses override methods in preference, such as startupEngin (BrokenTaxi), so it does not call Taxi’s startupEngine
- The output
BrokenTaxi indicates a BrokenTaxi, so the engine cannot be started. StartupEngine needs to be rewritten to tell the user that the engine cannot be started when he/she intends to start the engine
The standard delegation
Lazy properties
Class on first access
Lazy takes a lambda and returns a lazy instance that can be used as a delegate to implement the deferred property, passing the return value of the lambda expression to the property the first time it is used
By default, the delay attribute is initialized in a synchronous lock and is observed by all threads.
If you determine initialization will happen when used with attributes in the same thread, you can use LazyThreadSafetyMode. NONE mode: it will not have any thread safety guarantee and related costs, implementation code is as follows:
Val laze2: String by lazy (LazyThreadSafetyMode. NONE) {} "an-an in zhuo"Copy the code
Observable attribute
Listeners are notified of this property change
Observable properties are implemented in two ways: Observable and vetoable
The Observable method receives a callback when a property changes.
The vetoable method can also receive callbacks, but with vetoable we can intercept according to the condition, to determine whether to update the value of the property;
Create it as an Observable
When we change the value of field, the Lambuda expression is called back
Create it in vetoable mode
It is also important to create observable properties in a vetoable way, which can be intercepted in a Rambuda expression to determine whether the value of the property should be updated
Store properties in a map
We can delegate properties using a map map, where the map key is the name of the delegate property and the map value is the value of the delegate property
Local delegate property
Attribute delegate requirements
I should have done property delegation first, because I was slow to understand this when I first learned about delegates, so it might be easier for you to accept property delegation here if YOU look at the first thing.
The property delegate must provide a getValue method and, if it is a var property, a setValue method
- The basic principles of attribute delegation
- Property changes and method calls in the delegate class
Regarding attribute delegation, if the delegate attribute Field is set to var, then the delegate class ResourceDelete needs to implement both getValue and setValue methods.
So the following questions arise:
2. Do we call setValue every time we change the field reference? (Answer: yes)
There is too much code, I can’t put the screenshots down, let’s go to the code
After running the code, the validation of the above two conclusions is released
class EnTrustObject { var field: Resource by ResourceDelete() } class ResourceDelete { var resource: Resource = Resource(" initial object ") Operator Fun getValue(enTrustObject: enTrustObject, property: KProperty<*>): operator fun getValue(enTrustObject: enTrustObject, property: KProperty<*>): Resource {println(" call getValue method ") return Resource} Operator fun setValue(enTrustObject: enTrustObject, property: KProperty<*>, resource: Resource) {this. Resource = Resource println(" call setValue ")}} Class Resource(val value:String) {fun print() {this. Resource = Resource println(" call setValue ")}} Class Resource(val value:String) {fun print() { Println ("$value print Resource ")}} fun main() {EnTrustObject().apply {field.print() field= Resource(" changed object ") field.print() field.print() } }Copy the code
Delegate is implemented using the Lazy class
The description of the Lazy
Kotlin provides us with a Lazy class to help us implement more complex Lazy loading. The description of Lazy has been translated and screenshot below:
That is, Lazy allows us to do one thing, store the value of the property we want to fetch as value, and provide the isInitialized method to determine if the property has been initialized.
If already initialized, the value will not be reset when we get the property with the following code.
private val engine: Engine by engine()
Copy the code
Use Lazy to implement Lazy loading
We made an implementation like this:
Create a Car class. The Car class holds an Engine class. The Engine class is initialized using lazy loading.
Fun main() {Car().apply {myEngine() myEngine() myEngine()}} /** * class Car {private val engine: Engine by Engine () private val Engine 1: Funmyengine () {engine.showintroduce () engine1.showintroduce ()}} /** * Declare Engine class */ class Engine(private val describe: String) {funshowintroduce () {println(describe)}} /** * create an extension function to obtain the engine, */ funcar.engine (): LazyEngine {return LazyEngine()} /** * class LazyEngine {return LazyEngine()} Lazy<Engine> { private var cache: Engine? Override fun isInitialized(): Boolean {return cache! = null /** * If the engine cache is not empty, it has been initialized. Override val value: Engine get() {return if (cache == null) {return if (cache == null) {return if (cache == null) {return if (cache == null) { } else { cache!! }}}Copy the code
Code execution result:
If you want to learn more about Lazy loading, you are recommended to read the android ViewModel extension library for the initialization method of the ViewModel
Finally, I bring myself a salt:
Welcome to follow my public account “ananzhuo” to learn more knowledge