【Kotlin从入门到深坑】之类的属性和字段
2017-06-12 20:42
309 查看
简介
本篇博客主要是介绍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的方法,则是可读属性,反之亦然。
总结一波:通过上面的介绍我们了解了什么是属性以及什么是字段,在
java和
Kotlin中其含义是一致的。
属性和字段
声明属性
对于Kotlin的类可以有属性。我们之前也说过可以通过var声明可变属性,
val声明只读属性,或许你会问了,为什么不是叫字段而是叫属性呢?因为
Kotlin类中声明的变量,都会提供默认的
get、
set(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】可以推断出类型,则【类型】也可以省略。
属性通过
var和
val去声明得到只读属性和可变属性,那他们的区别究竟是什么呢?
只读属性和可变属性的区别:
只读属性使用
val声明,可变属性使用
var声明
只读属性不允许
setter
看到此处你或许会感叹
Kotlin的厉害之处,省了不知多少时间,但有些人或许会感叹了,如果我想自己定义属性的访问方法又怎么弄呢?像
java再自定义方法吗?会不会和默认的
setter或者
getter冲突呢?对于疑问我们一一解答。
自定义Getters和Setters
编写Getters和
Setters非常像一般的不同方法,在属性声明内部,举例:
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 又是什么鬼。。。
好,我们说明一下:
value是
setter的参数,其类型同于属性的类型,不爽你也可以换个其他名字。。
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后其
Getter和
Setter,都是私有的,外部都不可以访问也就是说
person._table是不允许的。也就进行了隐藏。又因为默认的
Setter和
Getter调用私有属性会被进行优化,所以不会引入函数调用开销。
编译期常量
在kotlin中已知值得属性可以使用
const标记为编译期常量。
它需要满足以下条件:
使用
val声明的常量
位于顶层或者
object的一个成员
用
String或者原生类型值初始化
没有自定义
Getter
延迟初始化属性
对于非空属性,在声明时必须对其进行初始化,如果想进行延迟初始化,可以使用lateinit标记,代码举例:
lateinit var name: String
需要注意以下几点:
该修饰符只能用于类体中不是方法中的属性
没有自定义
Setter或者
Getter
不能是原生类型(String可以,它不是原生类型)
如果在初始前访问
lateinit定义的属性会抛出特定异常,指明该属性没有被初始化。
总结一波:我们需要区分Kotlin中和java中使用属性的区别,对于
Koltin中使用【类名.属性】等同于java中的【类名.属性对应方法】,以及牢记
Setter的写法,别写错了,导致循环调用,熟练使用幕后字段。重写后的
Getter和
Setter会覆盖之前的默认方法并不会冲突
总结
至此已经学完了Kotlin的【类的属性和字段】的知识,多回顾多思考,继续后续内容。相关文章推荐
- 【Kotlin从入门到深坑】之类的属性和字段
- 【Kotlin从入门到深坑】之类的覆盖属性和方法以及抽象类
- Kotlin从入门到放弃之基础篇(四)——属性、字段、接口
- 【kotlin从入门到深坑】之类和继承
- Kotlin基础教程-属性和字段
- Kotlin 官方学习教程之属性和字段
- Kotlin学习(三): 属性和字段
- 【Kotlin从入门到深坑】之基础类型
- MyBatis入门学习教程 解决字段名与实体类属性名不相同的冲突
- Kotlin 字段和属性
- 【Kotlin从入门到深坑】之返回和跳转
- MyBatis入门03 解决字段名与实体类属性名不相同的冲突
- 深入Kotlin - 专项 - 幕后字段、幕后属性
- NDatabase 入门,简单使用 增删改查。让NDatabase带你脱离ADO.net,各种SQL 语句,各种DBMS,各种CRM,IOC之类的烦恼。我们也不需要仓库设计模式了,你妹的。不要表了,不要设计数据库字段了。就这样!
- Kotlin-属性和字段
- [kotlin系列] (s2_2)属性、字段、接口、可见性修饰
- android kotlin类和对象(二)-属性和字段
- C#OOP基础之类,字段,属性和方法。
- C#入门--字段与属性
- MyBatis入门学习教程-解决字段名与实体类属性名不相同的冲突