安卓Kotlin开发学习

您所在的位置:网站首页 kotlin高阶函数 安卓Kotlin开发学习

安卓Kotlin开发学习

2023-02-24 06:24| 来源: 网络整理| 查看: 265

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 17 天,点击查看活动详情

前言

上一篇我们说到在StringBuilder类写一个build()扩展函数为高阶函数时(安卓Kotlin开发学习——接着看高阶函数 - 掘金 (juejin.cn)):

image.png

我们说到这个类之前是无法使用在任意类上的,而本篇首先就是使用泛型让这个build()方法实现和apply()函数一模一样的功能,然后我们再去看Kotlin委托这一知识点

正文 泛型定义与使用

其实泛型在Kotlin的使用和在Java上使用没什么大的区别,如下,我们将前言中的例子给泛型化:

fun T.build(block: T.() -> Unit): T { block() return this } 复制代码

我们可以看到,和Java一样,我们也是用里换成T来将build定义成泛型函数,然后将原来的类名全替换为T即可,然后我们再调用它,就能和apply()函数一样了:

contentResolver.query(uri, null, null, null, null)?.build { while (moveToNext()) { } close() } 复制代码 委托 概念

这是一种设计模式,委托代表了操作对象不会自己去处理某段逻辑,把这一工作交付(委托)给另外一个辅助对象去实现。而Koltin的委托有两种,分别是类委托和委托属性。 接下来我们先看类委托:

类委托的使用方法

我们应该在Java开发安卓时就会接触到Set,这是一种类似List数据类型的,但存储数据是无序且不重复的,而且Set本体是一个接口,我们使用它需要使用它的实现类,例如HashSet,但如果我们借助委托模式,就能很方便的实现一个自己的实现类,如下,我们定义了一个TestSet,并用它实现Set接口,但并没有使用类委托的话:

class TestSet(val helperSet: HashSet) : Set { override val size: Int get() = helperSet.size override fun contains(element: T) = helperSet.contains(element) override fun containsAll(elements: Collection) = helperSet.containsAll(elements) override fun isEmpty() = helperSet.isEmpty() override fun iterator(): Iterator = helperSet.iterator() } 复制代码

虽然这个TestSet其实也是委托模式实现的(接受了一个HashSet参数为辅助对象,我们在Set接口的所有方法实现中都没有自己的实现,而是使用这个辅助对象的方法实现),我们可以把少部分方法实现自己重写或加入自己的方法就能使TestSet成为一个全新的数据结构类,但是如果我们需要实现的接口中待实现方法特别多,那真的很折磨,所以Kotlin中就有类委托这一办法去解决这个困扰:

class TestSet(val helperSet: HashSet) : Set by helperSet{ fun testPrint() = println("class entrust") } 复制代码

我们在接口声明后使用了关键字by ,再加上受委托的辅助对象,这就是类委托的写法,看函数体,我们免去了写一堆代码的痛苦,如果需要某一方法重写,就可以在函数体中单独重写那个方法即可,其他方法仍然可以依靠类委托自动实现。

属性委托的实现方法

学会使用类委托后,我们就知道了所谓的类委托就是把一个类的具体实现委托给另一个类去完成,所以我们推广之,属性委托就是把一个属性的具体实现委托给另一个类去完成,所以属性委托如下结构:

class TestAttributeEntrust { var attribute by Delegate() } 复制代码

属性委托给这个辅助对象类后,我们也要去实现这个类:

class Delegate { var propValue : Any? = null operator fun getValue(testAttributeEntrust: TestAttributeEntrust, prop: KProperty) : Any? { return propValue } operator fun setValue(testAttributeEntrust: TestAttributeEntrust, prop: KProperty, value: Any?) { propValue = value } } 复制代码

在Delegate类中我们写了getValue()方法和setValue()方法,并且用了关键词operator声明,这样写就能在我们调用attribute属性时候就会自动调Delegate类的get方法,而为attribute属性赋值时就会自动调Delegate类的set方法,上面代码中set和get方法中的第一个参数是表明在哪个类中使用的,而第二个参数KProperty则是一个属性操作类,可以获取各种属性相关值,符号中加* 号表明我们不知道或不关心泛值的具体类型,类似Java的中?的写法,只是为了通过语法编译,而Any?的返回值表明我们这个返回值可以声明成任何类型。

如果我们把attribute属性改为val关键字声明的,就不需要写setValue()方法,以为我们是无法把这个属性在初始化后再重新赋值的,所以val声明的属性实现属性委托只需要写getValue()方法即可。

总结

这里还有一些用法没说,后面在更新高阶函数的应用时候再添加上去,本篇就说到这里,基本上泛型和委托的知识都梳理了一遍。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3