Getters 与 Setters
可以为属性定义自定义的访问器。如果我们定义了一个自定义的 getter,那么每次访问该属性时都会调用它
如果我们定义了一个自定义的 setter,那么每次给属性赋值时都会调用它。
class Example {
var name : String = "123"
//自定义getter
get() = field+"111"
//自定义setter
set(value){
field = "$value"
}
}
var example = Example()
println(example.name)
example.name = "老虎"
println(example.name)
//输出
//System.out: 123111
//System.out: 老虎111
幕后字段
在 Kotlin 类中不能直接声明字段。然而,当一个属性需要一个幕后字段时,Kotlin 会自动提供。
这个幕后字段可以使用field标识符在访问器中引用:
class Example {
var name : String = "123"
get() = field
}
var example = Example()
println(example.name)
//输出
//System.out: 123
Android 项目使用Anko
Anko是JetBrains开发的一个强大的库。它主要的目的是用来替代以前XML的方式来使用代码生成UI布局。
Anko包含了很多的非常有帮助的函数和属性来避免写很多的模版代码。
1,首先依赖
app下的build.gradle ---> denpendencies
implementation "org.jetbrains.anko:anko-common:0.8.2"
2,使用Anko能帮助我们简化代码
在MainActivity:onCreate,一个Anko扩展函数可以被用来简化获取一个RecyclerView:
var recycler:RecyclerView = find(R.id.recyclerview)
扩展函数
扩展函数数是指在一个类上增加一种新的行为,甚至我们没有这个类代码的访问权限。
这是一个在缺少有用函数的类上扩展的方法。
Anko已经包括了自己的toast扩展函数。
Anko提供了一些针对CharSequence和resource的函数,还有两个不同的toast和longToast方法:
可以直接在Activity中调用
toast("Hello")
longToast("Anko is very good!")
with函数
with是一个非常有用的函数,它包含在Kotlin的标准库中。
它接收一个对象和一个扩展函数作为它的参数,然后使这个对象扩展这个函数。
这表示所有我们在括号中编写的代码都是作为对象(第一个参数)的一个扩展函数,我们可以就像作为this一样使用所有它的public方法和属性。
当我们针对同一个对象做很多操作的时候这个非常有利于简化代码。
class People(var name : String,var age : Int)
var people = People("东方不败",18)
with(people){
var a = name
var b = age
println("name---$a age---$b")
//输出 name---东方不败 age---18
}
扩展函数
声明一个扩展函数,我们需要用一个 接收者类型 也就是被扩展的类型来作为他的前缀。
fun MutableList<Int>.swap(index1: Int, index2: Int) {
val tmp = this[index1] // “this”对应该列表
this[index1] = this[index2]
this[index2] = tmp
}
val list = mutableListOf(1, 3, 5)
list.swap(0, 2) // “swap()”内部的“this”会保存“list”的值
list.forEach {
println(it)
}
//输出
//System.out: 5
//System.out: 3
//System.out: 1
扩展是静态解析的
扩展不能真正的修改他们所扩展的类。通过定义一个扩展,你并没有在一个类中插入新成员,
仅仅是可以通过该类型的变量用点表达式去调用这个新函数。
open class Shape
class Rectangle: Shape()
fun Shape.getName() = "Shape"
fun Rectangle.getName() = "Rectangle"
fun printClassName(s: Shape) {
println(s.getName())
}
printClassName(Rectangle())
//输出 Shape
这个例子会输出 “Shape”,因为调用的扩展函数只取决于参数 s 的声明类型,该类型是 Shape 类。
如果一个类定义有一个成员函数与一个扩展函数,而这两个函数又有相同的接收者类型、 相同的名字,
并且都适用给定的参数,这种情况总是取成员函数
class Example {
fun printFunType() { println("成员函数") }
}
fun Example.printFunType() { println("扩展函数") }
Example().printFunType()
//输出 成员函数
扩展的作用域
/**
* 扩展函数
*
* 不能写在class里边
*/
fun MutableList<Int>.swap(index1: Int,index2: Int){
val tmp = this[index1]
this[index1] = this[index2]
this[index2] = tmp
}
这样别的类也可以调用
数据类
只保存数据的类,在这些类中,一些标准函数往往是从数据机械推导而来的。在 Kotlin 中,这叫做 数据类 并标记为 data:
data class User(val name: String, val age: Int)
注意点:
* 主构造函数需要至少有一个参数;
* 主构造函数的所有参数需要标记为 val 或 var;
* 数据类不能是抽象、开放、密封或者内部的;
在类体中声明的属性
对于自动生成的函数,编译器只使用在主构造函数内部定义的属性。如需在生成的实现中排出一个属性,请将其声明在类体中:
data class Person(val name: String) {
var age: Int = 0
}