Kotlin相关基础及与Java的不同 的 笔记(仨) --拓展方法和属性代理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/heming9174/article/details/75312560

感觉学习进度越来越慢了,一个新的知识点需要学习好久.

22.

Kotlin的扩展方法和扩展属性
可以自定义方法和运算符啊
可以理解为 加强版的Utils
只需要遵循
fun X.Y():Z{}
X为类名
Y为自定义的扩展方法名称,可以进行传参
Z为扩展方法的返回值,如果返回值为Unit,可以省略
举个栗子

fun main(args: Array<String>) {
    //String肯定没有这种方法
    //拓展方法类似于工具类
    //当然在Kotlin内还有操作符进行扩展
    "0123456789".typewriter()
    println("abc"*6)
}

//fun X(String).Y()(typewrite()):Z{}(因为没有返回值,所以省略)
fun String.typewriter(){
    //逐字打印
    var arr = this.toCharArray()
    var stringBuffer = StringBuffer()
    for (i in 0 until arr.size){
        stringBuffer.append(arr[i].toString())
        println(stringBuffer.toString())
    }
}
//和上面的一样,只不过是有参数和返回值
operator fun String.times(int:Int):String{
    var sb = StringBuffer()
    for (i in 0 until int){
        sb.append(this)
    }
    return sb.toString()
}

都是String添加扩展方法,第一个是普通的扩展方法,第二个是 操作符扩展方法

扩展属性的话,没什么意义,其实就是setter/getter

var String.a:String
    set(value) {
    }
    get() = "abc"

val String.b:String
    get()="aaa"

fun main(args: Array<String>) {
    "aaa".a = "111"
    "aaa".a
    "bbb".b
}

只想说一句,我次奥,居然还有这种操作.
Java调用
原本以为又是添加注解,没想到居然不是
Java调用类似于添加了注解的静态方法,直接类名点方法名即可.
其中第一个参数receiver及对应的X的值.也就是Kotlin里面写的扩展方法的this

public static void main(String[] args) {
        Test3Kt.times("abc",4);
        Test3Kt.typewriter("0123456789");
    }

23.

Kotlin的属性代理
话说,之前有记录Kotlin的懒加载

val x by lazy {
    "hello"
}

比如这样,只有当变量x在使用的时候才进行加载,赋值为”hello”.
其中lazy就是代理
点下那个by,发现跳转的方法是:

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

也就是变量x在被调用的是,调用getValue(),赋值value即”hello”
创建一个类,把这个方法拷过来,创建属于自己的代理.
发现由于var是 读写权限,不仅仅需要getValue(),同时还需要setValue()

class OK {
    private var str :String ?= null
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
        println("我调用了OK的getValue,是通过${property.name} 调用的")
        return str?:""
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, str: String) {
        println("我调用了OK()的setValue方法,是通过${property.name}调用的,设置值为:$str")
        this.str = str
    }
}

class Normal {
    //val 只读
    val read by OK()
    //var 读写,所以必须要实现setValue()方法
    var write by OK()
}


fun main(args: Array<String>) {
    val n = Normal()
    //输出打印的是X().getValue()的值
    println(n.read)
    //未对write赋值,输出打印出来的还是OK().getValue()值,即""
    println(n.write)
    //进行赋值,会自动调用OK().setValue()方法
    n.write = "kotlin"
    //这次返回的即赋值后的getValue()
    println(n.write)
}
  • 自定义代理.val只读,只需要getValue(),var读写,还需要setValue().
  • 代理类,setValue()需要3个参数,需要添加一个参数进行设置
  • 创建的代理类,自定义了一个内部变量str,默认为null,在getValue()内当为null,返回”“,?:是Elvis操作符
  • 当进行赋值时,就会自动调用代理类的setValue()方法

这是输出结果:

我调用了OK的getValue,是通过read 调用的

我调用了OK的getValue,是通过write 调用的

我调用了OK()的setValue方法,是通过write调用的,设置值为:kotlin
我调用了OK的getValue,是通过write 调用的
kotlin

最后打印结果,因为调用n.read和n.write是默认调用OK().getValue(),即为””
对n.write进行赋值,会自动调用OK().setValue()
再次调用n.write,这次str的值为刚刚赋的值,即kotlin

猜你喜欢

转载自blog.csdn.net/heming9174/article/details/75312560