参考文档
Kotlin中文文档
http://www.kotlindoc.cn/ClassesAndObjects/Classes-and-Inheritance.html
简书
https://www.jianshu.com/p/011f3fbefd01
2. 属性
java中在包下面有类、接口等,而Kotlin中在包下面是可以直接有属性的,并且所有非抽象都强制要求初始化,没有初始化的属性无法通过变异(除标记为lateinit var的属性外)
a.声明
用var声明可变,用val声明不可变
在Kotlin中完整的声明格式:
var name: String = ""//初始化不能为null,如果需要赋值为null类型初始化为string?
abstract var size : Int//abstract用法与java一致
例2:
属性声明中的属性类型在大部分情况下是可以省略的。这里说的大部分是指我们的最多的使用情况,也就是默认的使用场景。
var age = 1
var sex = true
var name = ""
注:
修饰符
修饰符 | 作用范围 | 是否可以省略 |
---|---|---|
public | 默认的修饰符。全部可见,在属性被初始化时 | 如果可以根据属性的值推断出属性类型,则可省略类型 |
protected | 在本身和子类中可见 | 如果可以根据属性的值推断出属性类型,则可省略类型 |
private | 只在本身可见 | 如果可以根据属性的值推断出属性类型,则可省略类型 |
abstract | 在自身不初始化,需要子类进行初始化 | 不能省略类型 |
例3:
类中的属性,用.进行访问例如上面的name属性,我们可以这样进行读写操作
p1.age = 21
tv.setText("p1's name:"+p1.name+"\np1's age:"+p1.age)
b.getter和setter方法
注意 :
val 只读属性不可以有 setter
例1:
默认方法
Kotlin调用属性的方法虽然与java为public的属性的调用方法类似,但,两者意义不同
语言 | 意义 |
---|---|
java | 针对与属性的作用域的范围进行的直接调用 |
Kotlin | 对于属性的get和set方法的隐式调用 |
完整写法:
var name:String
get() = name
set(value) {
name = value
}
例2:
访问权限
属性都是有get和set方法的,当我们不想对外公开某个方法时,可以使用修饰符private实现
var name:String
get() = name
private set(value) {
name = value
}
但是这种方式只适用于set方法,get的访问权限默认是和属性一致的,下面的使用会报编译错误
例3:
自定义getter和setter
var有set和get,val只有get
// 自定义get
var size: Int = 2
get() = if (field > 10) 15 else 0
// 调用
var pf = PropertiesFields()
pf.size = 5
Log.d("text", "size : ${pf.size}")
pf.size = 20
Log.d("text", "size : ${pf.size}")
// 输出
size : 0
size : 15
// 自定义set
var size: Int = 2
set(value) {
field = if (value > 10) 15 else 0
}
// 调用和输出同上
作者:我爱吃栗子啊
链接:https://www.jianshu.com/p/47676dc8c27a
來源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
c.Backing Fields
Kotlin中,并不允许使用局部变量,在自定义getter和setter的时候,因为属性的调用也是对get的调用,因此会产生递归,造成内存溢出。可以使用field来起到局部变量的作用。
例1
var name:String = ""
get() = field
set(value) {
field = if (value.equals("10")) "15" else "0"
}
注意:field标识符只允许在属性的访问器函数内使用.
d.Backing Properties
它实际上也是隐含试的对属性值的初始化声明,避免了空指针
//oop.Person.kt
class Person(val name:String)
val maxId = Int.Max_value
//maxId被编译为这个类私有的静态字段,并拥有一个默认的getter方法。在java中是直接通过类名.maxID,而在Kotlin中是这么用的:
//Kotlin调用包级属性
import oop.maxID//因为是包级变量,所以使用"包名.属性"的方法导入
val a = maxID//直接调用,不需要注明变量所在的文件
例2:
编译器常量与包级属性类似
//oop.Person.kt
const val maxID = Int.MAX_VALUE//将maxID声明为编译器常量
与java相比,Kotlin中常量有几个限制:
1.只能定义在类外或对象(Object)内
2.只能使用string或原生类型(Int、Double等)初始化
3.不能自定义getter(直接调用,不需要gtter)
注意:
Kotlin中,使用在注解参数中的属性,只能是编译器常量(其他形式的属性都不能使用在注解的参数里)