【Kotlin从入门到深坑】之类的属性和字段

简介

本篇博客主要是介绍Kotlin语法中的【类的属性和字段】相关的知识,帮助各位更快的掌握Kotlin,如果有疏漏或者错误,请在留言中指正,谢谢。 系列汇总地址


基础知识

定义

在讲解之前我感觉有很多人根本不清楚什么是属性,什么又是字段,我们先简单说明一下。

简单理解:

  • 字段,通常叫做类成员或者类成员变量,理解为"数据成员",用来承载数据。

  • 属性,通常可以理解为set和get方法。其属名性时根据get和set方法名得出的,规则是:去掉get或set后其剩余的字符串,属性大多是对字段的封装,限制其访问和写入。

具体说明(以java为例):

  • 字段,在类中定义的成员变量。
public class A{
   private String s = "123";
}

我们可以描述为A类中有个s字段

  • 属性,只局限于类中方法的声明,并不与类中其他成员相关。
void setA(String s){}
String getA(){return s}

当一个类中拥有这样一对方法时,我们可以说,这个类中拥有一个可读写的a属性(注意是小写a)。如果去掉了set的方法,则是可读属性,反之亦然。

总结一波:通过上面的介绍我们了解了什么是属性以及什么是字段,在javaKotlin中其含义是一致的。


属性和字段

声明属性

对于Kotlin的类可以有属性。我们之前也说过可以通过var声明可变属性,val声明只读属性,或许你会问了,为什么不是叫字段而是叫属性呢?因为Kotlin类中声明的变量,都会提供默认的getset(val没有该方法)方法,所以声明的都是属性。Kotlin中没有字段,只有幕后字段(backing filed)。

我们声明的时候大都采用下面的形式:

class People {
    var name: String? = null
    var address: String = "地球"
    var age: Int? = null

}

你或许会说,属性是有get、set方法的(不仅限于此),那Kotlin自己实现的怎么用呢?

 var people=People() //声明实例,不需要new
 people.name //直接使用,内部会调用访问方法

上面我们看到使用起来还是比较简单的。类似于我们java中声明了私有变量,然后提供了set、get方法,到达属性的目的。


Getters和Setters

声明一个属性的完整语法如下:

【属性修饰符(var、val)】+【属性名称】+ 【:】 + 【类型】 = 【初始化】
【gettter】
【setter】

对于【初始化】和【getter】和【setter】都是可选的,如果通过【初始化】的值或者【getter】可以推断出类型,则【类型】也可以省略。

属性通过varval去声明得到只读属性和可变属性,那他们的区别究竟是什么呢?

只读属性和可变属性的区别:

  • 只读属性使用val声明,可变属性使用var声明

  • 只读属性不允许setter

看到此处你或许会感叹Kotlin的厉害之处,省了不知多少时间,但有些人或许会感叹了,如果我想自己定义属性的访问方法又怎么弄呢?像java再自定义方法吗?会不会和默认的setter或者getter冲突呢?对于疑问我们一一解答。


自定义Getters和Setters

编写GettersSetters非常像一般的不同方法,在属性声明内部,举例:

Getters方法:

var name: String? = null //声明name属性
        get() {//重写get方法
            return "hhh" 
        }
 var people=People()
 people.name

此处的name的值便是hhh,且无论name设置成什么值。

Setters方法:

 set(value) {//错误写法
     name=value //1)
 }

在此不知道有没有人看出不对的地方,上面 1) 处会导致循环调用,为什么呢?当你对属性赋值的时候就会调用set方法,当你获取属性的值得时候就会使用get方法。所以上面会一直循环调用set方法。

下面我们看看正确的怎么写:

set(value) {
    field=value
}

看完上面的代码,你应该有两个疑问,1.value 是什么鬼,field 又是什么鬼。。。

好,我们说明一下:

  • valuesetter的参数,其类型同于属性的类型,不爽你也可以换个其他名字。。

  • field就是我们之前说的幕后字段,用于将真正的值赋值给属性,而不会导致循环调用。它只能在属性的访问器中使用。这个也是可选项,有的时候必须(比如上面的Setter),有的时候不是必须(比如上面的Getter)。

如果上面的幕后字段仍然不能满足你...还有更猛的,幕后属性。

 private var _table: HashMap<String, String>? = null//私有属性
 var table: HashMap<String, String>? = null 
    get() {
            if (_table == null) {
                _table = HashMap<String, String>()
            }
            return _table //返回私有属性
     }

上面的代码需要特殊说明一下,当属性被定义为private后其GetterSetter,都是私有的,外部都不可以访问也就是说 person._table 是不允许的。也就进行了隐藏。又因为默认的SetterGetter调用私有属性会被进行优化,所以不会引入函数调用开销。


编译期常量

kotlin中已知值得属性可以使用const 标记为编译期常量。

它需要满足以下条件:

  • 使用val声明的常量
  • 位于顶层或者object的一个成员
  • String或者原生类型值初始化
  • 没有自定义Getter

延迟初始化属性

对于非空属性,在声明时必须对其进行初始化,如果想进行延迟初始化,可以使用lateinit标记,代码举例:

lateinit var name: String

需要注意以下几点

  • 该修饰符只能用于类体中不是方法中的属性
  • 没有自定义Setter或者Getter
  • 不能是原生类型(String可以,它不是原生类型)

如果在初始前访问lateinit定义的属性会抛出特定异常,指明该属性没有被初始化。

总结一波:我们需要区分Kotlin中和java中使用属性的区别,对于Koltin中使用【类名.属性】等同于java中的【类名.属性对应方法】,以及牢记Setter的写法,别写错了,导致循环调用,熟练使用幕后字段。重写后的GetterSetter 会覆盖之前的默认方法并不会冲突


总结

至此已经学完了Kotlin的【类的属性和字段】的知识,多回顾多思考,继续后续内容

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349

推荐阅读更多精彩内容