zoukankan      html  css  js  c++  java
  • 属性委托深入详解

    在上一次https://www.cnblogs.com/webor2006/p/11369019.html中学习了类委托,这次来学习一下属性的委托(delegated property),我们知道定义一个类的属性是需要给它一个初始值的,如果不给会报错,如下:

    当然啦,可以加一个延迟属性来避免:

    当然咱们不用这种方式,而是可以将此属性的赋值进行委托,目前该属性是可读可写,则在委托属性中需要定义可读可写的,而如果是用的val定义的属性则只需要定义可读的委托属性,具体如何做呢?下面先来定义一个委托类:

    接下来需定义两个读写方法,注意:该方法的名称是有严格要求的,不能乱写方法名,下面来定义一下:

    接下来则需要给它定义参数,第一个参数是要给哪个类进行委托,第二个参数是其委托的属性是哪一个,定义如下:

    接下来再来定义setValue()方法,此时因为需要设置值,所以多了一个参数,其函数的参数大体跟getValue()差不多:

    接下来则将这个委托关联到我们的属性上,如下:

    下面咱们来调用一下:

    从打印来看其值的读写确实是被委托了,其中特别要强调的是:

    其中这里使用了运算符重载,貌似C++中也有这个关键字,如下:

    那对于委托属性在实际开发中是有如下4种使用情况的:

    1、延迟属性。

    2、可观测属性。

    3、非空属性。

    4、map属性。

    延迟属性:

    这次先来对延迟属性和非空属性进行学习一下,先来看啥叫延迟属性:它指的是属性只有第一次被访问的时候才会计算,之后则会将之前的计算结果缓存起来供后续调用。下面看个具体例子:

    下面来使用一下:

    其中lazy是个函数,咱们来看一下它的声明:

    好奇怪的写法,很显然咱们是将Lambda表达式写在了方法体中,而非方法参数中:

    关于Kotlin的Lambda表达式跟Java8的Lambda表达式是不一样的,这个在之后会专门再学,这里之所以能写在方法体中是有这样一个规则:如果一个方法的最后一个参数是Lambda表达式,则直接可以将它写在方法体中。

    另外lazy函数还有另外一个重载的版本,如下:

    而该模式是被定义成了一个枚举类型:

    所以咱们可以简单的使用一下这种重载的方法:

    所以下面对这三种模式再总结一下:

    1、SYNCHRONIZED:默认情况下,延迟属性的计算是同步的;值只会在一个线程中得到计算,所有的线程都会使用相同的一个结果。

    2、PUBLICATION:如果不需要初始化委托的同步,这样多个线程可以同时执行。

    3、NONE:如果确定初始化操作只会在一个线程中执行,这样会减少线程安全方面的开销。

    非空属性

    先来看一下代码:

    我们知道对于定义的属性是必须要给它赋初值的,不然就报错了,但是如果没有一个合适的初值能赋给它,此时就可以将它委托给非空属性,如下:

    其中看一下Delegated:

    接着来看一下notNull()的说明:

    其中它的实现是实例化了NotNullVar,如下:

    而它的定义如下:

    它实现了ReadWriteProperty这个接口,如下:

    也就是系统对于委托的这俩函数已经定义好了,关于这个接口在未来还会学习的。好,接下来咱们来使用一下它:

    那。。如果不赋值就直接读取呢?

    确实如javadoc所说。所以notNull通常适用于那些无法在初始化阶段就确定属性值的场合。

  • 相关阅读:
    【 数据结构(C语言)】栈的应用——行编辑程序
    【 数据结构 (C语言)】栈的应用(二)——括号匹配问题
    节点
    页面加载--延迟加载
    雅黑php 探针
    Swiper 触屏滑动切换
    tab 选择悬停展示
    翻牌抽奖功能讲解
    公告信息滚动功能
    织梦提交表单不进行跳转
  • 原文地址:https://www.cnblogs.com/webor2006/p/11369333.html
Copyright © 2011-2022 走看看