3.kotlin Notes_Agent

Keywords: Attribute JSON

1. Agent mode

    interface Base {
        fun printMessage()
        fun printMessageLine()
    }

    class BaseImpl(val x: Int) : Base {
        override fun printMessage() { print(x) }
        override fun printMessageLine() { println(x) }
    }

    class Derived(b: Base) : Base by b {
        override fun printMessage() { print("abc") }
    }

    @Test
    fun test17() {
        val b = BaseImpl(10)
        Derived(b).printMessage()//Execute method abc overridden in its own class
        Derived(b).printMessageLine()//Execution Agent Class Execution Method 10
    }

It is important to note that members of this override can only be accessed by themselves, that their proxy objects cannot be accessed, and that proxy objects can only access their own members:

    interface Base {
        val message: String
        fun print()
    }

    class BaseImpl(val x: Int) : Base {
        override val message = "BaseImpl: x = $x"
        override fun print() { println(message) }
    }

    class Derived(b: Base) : Base by b {
        // This property is not accessed from b's implementation of `print`
        override val message = "Message of Derived"
    }

    @Test
    fun test18() {
        val b = BaseImpl(10)
        val derived = Derived(b)
        derived.print()
        println(derived.message)
    }

Execution results:
BaseImpl: x = 10
Message of Derived

2. Attribute Delegation

    class Delegate {
        operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
            return "$thisRef, thank you for delegating '${property.name}' to me!"
        }

        operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
            println("$value has been assigned to '${property.name}' in $thisRef.")
        }
    }

    class Example {
        var p: String by Delegate()
    }

    @Test
    fun test19(){
        val e = Example()
        e.p = "aaa"
        println(e.p)
    }

Execution results:
aaa has been assigned to 'p' in com.aislli.ktdemo.KotlinTest3Example@6f75e721.com.aislli.ktdemo.KotlinTest3Example@6f75e721.com.aislli.ktdemo.KotlinTest3Example@6f75e721, thank you for delegating 'p' to me!

3. kotlin provides several common standard proxy methods

3.1 lazy

val lazyValue: String by lazy {
    println("first!")
    "Hello"
}

@Test
fun test20() {
    println(lazyValue)
    println(lazyValue)
}

Execution results:
first!
Hello
Hello
Only the first time you get the value of the field, a series of processing operations in lazy {} are performed, and the result is returned as lamdba to initialize the value of the field and store it. When you get the value of the field again, the operation is no longer performed and the previously stored value is returned directly.

3.2 observable

class User {
    var name: String by Delegates.observable("<no name>") {
        prop, old, new ->
        println("$old -> $new")
    }
}

fun test16() {
    val user = User()
    user.name = "first"
    user.name = "second"
}

Execution results:
-> first
first -> second
The three parameters represent:
prop: assigned attribute
Old: old value
New: new value
If you want to prohibit modifying old values, you can use vetoable:

    class User {
        var age: Int by Delegates.vetoable(0) {
            property, oldValue, newValue ->
            println("${property.name}:$oldValue:$newValue")
            false
        }
    }
    @Test
    fun test16() {
        val user = User()

        user.age = 1
        user.age = 2
    }

Execution results:
age:0:1
age:0:2

3.3 map

    class User(map: Map<String, Any?>) {
        val name: String by map
        val age: Int     by map
    }

    @Test
    fun test21() {
        val user = User(mapOf(
                "name" to "John Doe",
                "age"  to 25
        ))
        println(user.name) // Prints "John Doe"
        println(user.age)  // Prints 25
    }

Use the map's capabilities to proxy assignments in processes such as JSON parsing, for example, the map proxy in the example above does something similar to the following:

    var name: String = map["name"] as String
    var age: Int = map["age"] as Int

Posted by irving on Tue, 10 Mar 2020 09:12:31 -0700