android 方法 委托,Android kotlin 委托

1 类委托

interface Base {

fun print()

}

class BaseImpl(val x: Int) : Base {

override fun print() { print(x) }

}

class Derived(b: Base) : Base by b

fun main(args: Array) {

val b = BaseImpl(10)

Derived(b).print() // 输出 10

}

Derived 的超类型列表中的 by句表示b 将会在 Derived 中内部存储。 并且编译器将成转发给 b 的所有 Base 的法。

2 委托属性

class Example {

var p: String by Delegate()

}

语法是: val/var : by 。

属性对应的 get()(和 set() )会被委托给表达式的getValue() 和 setValue()。

第一个参数是 p 所在对象的引用、第二个参数保存了对 p属性自身的描述;

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.'")

}

}

对于只读属性(即 val 声明的),委托必须提供名为 getValue 的函数,该函数接受以下参数:

thisRef 必须与属性所有者类型(对于扩展属性指被扩展的类型)相同或者是它的超类型。

property 必须是类型 KProperty或其超类型。

这个函数必须返回与属性相同的类型(或其类型)。

对于可变属性(即 var 声明的),委托必须额外提供 setValue 的函数,该函数接受以下参数:

thisRef 同 getValue() ;

property 同 getValue() ;

new value 必须和属性同类型或者是它的超类型。

getValue() 或/和 setValue() 函数可以通过委托类的成员函数提供或者由扩展函数提供。 两函数都需要 operator 关键字来标记。

委托类可以实现包含所需 operator 方法的 ReadOnlyProperty 或 ReadWriteProperty。

这俩接口是在 Kotlin 标准库中声明的:

interface ReadOnlyProperty {

operator fun getValue(thisRef: R, property: KProperty): T

}

interface ReadWriteProperty {

operator fun getValue(thisRef: R, property: KProperty): T

operator fun setValue(thisRef: R, property: KProperty, value: T)

}

3 延迟属性 Lazy

val lazyValue: String by lazy {

"Hello"

}

延迟加载属性(lazy property): 属性值只在初次访问时才会计算;

get()会执行lambda表达式并记录结果,后续的get方法将只返回结果。

var类型属性不能设置为延迟加载属性,因为在lazy中并没有setValue(…)方法。

lazy操作符是线程安全的。如果在不考虑多线程问题或者想提高更多的性能,也可以使

用 lazy(LazyThreadSafeMode.NONE){ … } 。

在LazyThreadSafetyMode中声明了几种,[Lazy]实例在多个线程之间同步访问的形式:

SYNCHRONIZED:锁定,用于确保只有一个线程可以初始化[Lazy]实例。

PUBLICATION:初始化函数可以在并发访问未初始化的[Lazy]实例值时调用几次,,但只有第一个返回的值将被用作[Lazy]实例的值。

NONE:没有锁用于同步对[Lazy]实例值的访问; 如果从多个线程访问实例,是线程不安全的。此模式应仅在高性能至关重要,并且[Lazy]实例被保证永远不会从多个线程初始化时使用。

class App : Application() {

val database: SQLiteOpenHelper by lazy {

MyDatabaseHelper(applicationContext)

}

override fun onCreate() {

super.onCreate()

val db = database.writableDatabase

}

}

4 可观察属性(Observable)

Delegates.observable() 函数接受两个参数:

第一个是初始化值,

第二个是属性值变化事件的响应器(handler).

这种形式的委托,采用了观察者模式,其会检测可观察属性的变化,当被观察属性的setter()方法被调用的时候,响应器(handler)都会被调用(在属性赋值处理完成之后)并自动执行执行的lambda表达式,同时响应器会收到三个参数:被赋值的属性, 赋值前的旧属性值, 以及赋值后的新属性值。

class ViewModel(val db: MyDatabase) {

var myProperty by Delegates.observable("") {

d, old, new ->

db.saveChanges(this, new)

}

}

5 Map中映射值

在像解析 JSON 或者做其他“动态”事情中。把map映射到属性

import kotlin.properties.getValue

class Configuration(map: Map) {

val width: Int by map

val height: Int by map

val dp: Int by map

val deviceName: String by map

}

conf = Configuration(mapOf(

"width" to 1080,

"height" to 720,

"dp" to 240,

"deviceName" to "mydevice"

))

6 局部委托属性

你可以将局部变量声明为委托属性。

memoizedFoo 只有someCondition满足条件,第一调用才会初始化

fun example(computeFoo: () -> Foo) {

val memoizedFoo by lazy(computeFoo)

if (someCondition && memoizedFoo.isValid()) {

memoizedFoo.doSomething()

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值