----《第一季Kotlin崛起:次世代Android开发 》学习笔记
总目录:每天学一点 Kotlin ---- 目录
上一篇:每天学一点 Kotlin -- 类的构造函数
下一篇:每天学一点 Kotlin -- 类的进阶:继承
1. 属性
1.1 在类定义中的属性可以有很多类型,比如 Int,Double,Boolean,String,还可以是其他自己定义的类。
1.2 函数也可以作为类的属性,举个栗子:
class NumberCompution(val num1: Int, val num2: Int, var operator: (Int, Int) -> Int){
fun operation(){
println("Operation Result: ${operator(num1, num2)}")
}
}
fun main(args: Array<String>) {
val numComp = NumberCompution(10, 20, {x, y -> x + y})
numComp.operation()
numComp.operator = {x, y -> x * y} // 给属性变量重新赋值
numComp.operation()
}
打印结果:
Operation Result: 30
Operation Result: 200
在主体中有返回值,但是省略 return,我们可以直接写要返回的结果。
1.3 在类中定义函数属性不需要特别谨慎,因为 Kotlin 仍然建立在 JVM 虚拟机上,而目前的 JVM 处理垃圾的方式基本上是根搜索法,即使是互相引用,也能被正常释放。
2. 属性的赋值和取值(setter 和 getter)
2.1 setter 和 getter:对属性是否可修改和是否可外部访问的描述。
2.2 比如在下面的这个类中:
class CustomType{
var nameA = "nameA"
val nameB = "nameB"
}
(1) getter: nameA 和 nameB 在类外部都可以通过 . 号获取的各自的值,所以都有 getter;
(2) setter: nameA 在类内部或外部都是可以修改的,而 nameB 在初始化后是不能修改的。所以 nameA 具有 setter,而 nameB 不具有 setter。
2.3 对于只读属性:
(1) 只读属性用 val 代替 var
(2) 只读属性不允许 setter
2.4 setter 和 getter 的使用:
fun main(args: Array<String>) {
testPerson2()
}
fun testPerson2() {
var person2 = Person2(16)
println("isAudlt: " + person2.isAudlt)
person2.addAge = 20
println("isAudlt: " + person2.isAudlt)
}
class Person2(age: Int){
var age = age
val isAudlt: Boolean
get() = age >= 18
var addAge: Int
get() = 0
set(value){
age += value
}
}
打印结果:
isAudlt: false
isAudlt: true
2.5 如果需要一个属性在类的内部能够修改它,但是在外部不能修改它,我们可以把 setter 隐藏起来,也就是使用 private 来修饰 setter。举个栗子:
fun main() {
testPerson3()
}
fun testPerson3() {
var person3 = Person3(26)
println(person3.isAudlt)
person3.age = 20
println(person3.isAudlt)
person3.addAge = 10
println(person3.isAudlt)
// person3.isAudlt = false // 编辑器直接报红线了
}
class Person3(age: Int){
var age: Int = age
var isAudlt: Boolean = false
private set
var addAge: Int = 0
set(value){
age += value
if(age >= 18){
isAudlt = true
}
}
}
打印结果:
isAudlt: false
isAudlt: true
isAudlt: true
属性 isAudlt 虽然定义的是 var,但是用了 private set,所以只有在类的内部能够修改,在外部不能给它设置值,因为 set 在外部是不可见的。在 addAge 这个属性的 setter 处加了一个判断,如果自增后的年龄大于等于18,那么 isAdult 就设置为 true 了。但是有一点一定要注意:当我们在构造的时候传入 age 或者在构造完成后手动修改 age,即使 age 大于等于18也不会改变 isAdult 的值,因为在构造的时候不会触发任何 setter,而在构造完成后修改属性时没有相应的 setter 对 isAdult 进行修改。
2.6 注意:在构造时是不会触发和调用任何 setter 的。
3. 幕后字段
3.1 在 setter 中赋值:在 setter 中如何对当前属性赋值呢?在 setter 中赋值,这个属性改变后不是再一次触发 setter 了么,这不就是无限循环了么?要解决这个问题,Kotlin 提供了一个很好的机制,那就是幕后字段。
3.2 举个栗子:
fun main() {
testPerson4()
}
fun testPerson4() {
println("testPerson4 start... ")
var person4 = Person4(25)
println(person4.isAudlt)
person4.age = 20
println(person4.isAudlt)
person4.addAge = 10
println(person4.isAudlt)
}
class Person4(age: Int) {
var isAudlt = false
private set
var age: Int = age
set(value) {
field = value
if (age >= 18) {
isAudlt = true
}
}
var addAge: Int = 0
set(value) {
age += value
}
}
打印结果:
testPerson4 start...
false
true
true