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
}