IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> kotlin语言学习 -> 正文阅读

[移动开发]kotlin语言学习

内联扩展函数

Kotlin系列之let、with、run、apply、also函数的使用

kotlin操作符

Kotlin中 ?、!!、?:、:: 、->符号的简单说明

kotlin协程

Kotlin 协程实战进阶(二、进阶篇:协程的取消、异常处理、Channel、Flow)

kotlin委托

Kotlin by 关键字

Kotlin by属性委托

by关键字得作用是实现委托模式

kotlin中,委托主要用处有两类

? ? ? ? 1.类委托.

类似于接口继承和组合.在声明类时采用如下方式

class ClassA(
//接口B的实现类
val interB:InterfaceB,
//接口C的实现类
val interB:InterfaceC,
...
//自定义的属性
}:InterfaceB by interB,InterfaceC by interC{
...
}
//使用方法
classA().methodInterfaceB()
classA().methodInterfaceC()
//把kotlin代码反编译为java代码,发现实现原理,相当于编译器帮我们在ClassA内部实现了B和C接口的方法,并在接口方法内部,调用了by委托的实例的实现方法.
//例如
class ClassA implement InterfaceB,InterfaceC{

final InterfaceB interB;
final InterfaceC interC;

    ClassA(InterfaceB interB,InterfaceC interC){
        this.interB=interB;
        this.interC=interC;
    }

    public void methodInterfaceB(){
        interB.methodInterfaceB();
    }

    public void methodInterfaceC(){
        interC.methodInterfaceC();
    }
}

? ? ? ? 2.属性委托

相比于类委托,多用于解决多继承问题,用的比较少.属性委托用处更多.kotlin中经常使用的延迟加载by lazy{}方法就是kotlin提供的模板属性委托方法

//属性委托的格式
val/var <属性名>:<类型> by <表达式>

这里的表达式主要是指setValue/getValue表达式.在完整的格式中,点击ctrl+左键点击by就可以找到对应表达式的实现

下面分析下常用属性委托的实现

2.1 延迟加载 by lazy{}

单击by,找到如下实现

@kotlin.internal.InlineOnly
public inline operator fun <T> Lazy<T>.getValue(thisRef: Any?, property: KProperty<*>): T = value

(这里需要补充扩展函数的知识,kotlin中允许通过扩展函数,在其他文件中为指定的类,添加新的功能方法)

恰好lazy{}返回的就是一个lazy<T>对象

同时,发现lazy<T>实现的只有getValue方法,没有setValue方法,所以by lazy{}只支持val属性的初始化,得到了一个新的解释

2.2 利用map映射来缓存属性

用法如下

classA(
    val map:Map<Any,String>
){

val name:String by map
val time:String by map
}

这里相当于是每次获取name/time的值,通过map的查询同名key获得对应的映射value

通过在编辑器中点击by,可以找到如下实现

//map只支持getValue
@kotlin.internal.InlineOnly
public inline operator fun <V, V1 : V> Map<in String, @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1 =
    @Suppress("UNCHECKED_CAST") (getOrImplicitDefault(property.name) as V1)

//mutableMap支持getValue/setValue方法
@kotlin.jvm.JvmName("getVar")
@kotlin.internal.InlineOnly
public inline operator fun <V, V1 : V> MutableMap<in String, out @Exact V>.getValue(thisRef: Any?, property: KProperty<*>): V1 =
    @Suppress("UNCHECKED_CAST") (getOrImplicitDefault(property.name) as V1)

@kotlin.internal.InlineOnly
public inline operator fun <V> MutableMap<in String, in V>.setValue(thisRef: Any?, property: KProperty<*>, value: V) {
    this.put(property.name, value)
}

2.3 kotlin提供的模板接口

经过2.1和2.2的学习,可以得知一个类要支持属性委托,需要支持属性的设置和获取方法

kotlin中提供了标准的接口,只要支持该接口,那么实现类就可以实现属性委托

//val属性的实现接口
public fun interface ReadOnlyProperty<in T, out V> {
    /**
     * Returns the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @return the property value.
     */
    public operator fun getValue(thisRef: T, property: KProperty<*>): V
}


//var属性的实现接口
public interface ReadWriteProperty<in T, V> : ReadOnlyProperty<T, V> {
    /**
     * Returns the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @return the property value.
     */
    public override operator fun getValue(thisRef: T, property: KProperty<*>): V

    /**
     * Sets the value of the property for the given object.
     * @param thisRef the object for which the value is requested.
     * @param property the metadata for the property.
     * @param value the value to set.
     */
    public operator fun setValue(thisRef: T, property: KProperty<*>, value: V)
}

kotlin变量

kotlin中声明变量

/**
 * kotlin声明
 * var代表可变变量,可以重复赋值
 * val代表final变量,只能赋值1次
 * 默认public可以直接外部访问,实际上是通过get/set方法来访问(val只有get方法),反编译可以证实
 * 增加private,编译器不会增加get/set方法,减少了冗余代码
 * 可以通过其他方式,让val可以重复赋值
 */
var name:String="time"
name="date"
[java]
public String name="time"
setName("date")

val name:String="hello"
name="world"===>error:编译出错
[java]
public final String name="hello"

在kotlin中,可以通过Backing properties来使val属性可以重复赋值

参考kotlin文档:??Backing propertiesicon-default.png?t=M666https://kotlinlang.org/docs/properties.html#backing-properties

private var _table: Map<String, Int>? = null
public val table: Map<String, Int>
    get() {
        if (_table == null) {
            _table = HashMap() // Type parameters are inferred
        }
        return _table ?: throw AssertionError("Set to null by another thread")
    }

这样在访问table属性时,表现出val特性,只能使用,不能更改

通过修改私有的_table变量,又可以改变table属性,实现原理如下,又涉及到kotlin到java的反编译处理

//这个现象背后的实现原理是这样的
//var和val的定义格式如下
var <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
    [<setter>]

val <propertyName>[: <PropertyType>] [= <property_initializer>]
    [<getter>]
//[]内的属性是可选的
//property_initializer是初始化属性
//如果val的定义格式如下
val <propertyName>[: <PropertyType>] 
    [<getter>]
//缺失了初始化属性的情况下,kotlin编译器,会把val属性编译为一个final修饰的get方法,而不是final修饰的属性
//这样,final修饰方法只是限制了方法不能重写,而不会限制方法返回
[kotlin]
val name:String
get()="time"
[java]
public final getName(){
    return "time"
}

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-07-17 16:34:46  更:2022-07-17 16:36:06 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 3:24:53-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码