關鍵字
-
Object:
簡化生成靜態(tài)內部類
生成匿名內部類對象
-
生成單例對象
如果object只是聲明,它代表一個靜態(tài)內部類。如果用變量接收object表達式,它代表一個匿名內部類對象。
object Admin { private var username = "admin" private var password = "admin" fun info(): String { return "${this.username}/${this.password}" } fun changePassword(password:String){ this.password = password } } fun main(args: Array<String>) { Admin.changePassword("new-password") println(Admin.info()) // admin/new-password }
-
伴生對象:
- 可以把伴生對象看成是一個普通Java類的單例對象,因為它最終也是按照普通類對象進行編譯的,只不過默認給你生成了一個唯一的實例。
- Kotlin為什么沒有static的東西,我覺得第一個原因是我們不僅可以引用一個kt文件中的類,也可以引用它所定義的變量以及方法,完全可以用這種方式實現(xiàn)所謂的靜態(tài)屬性以及靜態(tài)方法;如果前面的方式不能滿足需求,companion object帶給我們的優(yōu)勢是我們可以像對待其他普通類一樣繼承類或實現(xiàn)接口,相對于static class給我們帶來了更大的自由度
class Admin { companion object { private var username = "admin" private var password = "admin" fun info(): String { return "${this.username}/${this.password}" } fun changePassword(password:String){ this.password = password } } } fun main(args: Array<String>) { Admin.changePassword("new-password") println(Admin.info()) // admin/new-password Admin.changePassword("new-password2") println(Admin.info()) // admin/new-password2 }
-
By:
-
類的代理 class
//kotlin代理 編譯后實為java中的靜態(tài)代理 interface Animal{ fun bark() } class Dog : Animal { override fun bark() { println("DOG's Bark()") } } class Zoo(animal: Animal) : Animal by animal { override fun bark() { println("ZOO’s Bark") } } fun main(args: Array<String>) { Zoo(Dog()).bark() }
interface Base { val message: String fun print() } class BaseImpl(val x: Int) : Base { override val message = "BaseImpl: x = $x" override fun print() { println(message) } } class Derived(b: Base) : Base by b { // 在 b 的 `print` 實現(xiàn)中不會訪問到這個屬性 override val message = "Message of Derived" //但是在復寫了print方法后,執(zhí)行的依然是Derived的print方法調用的本類中的成員變量 // override fun print() { // println(message) // } } fun main() { val b = BaseImpl(10) val derived = Derived(b) derived.print() println(derived.message) }
屬性延遲加載 lazy
監(jiān)聽屬性變化 Delegates.observable ( 擴展 Delegates.vetoable )
自定義監(jiān)聽屬性變化 ReadWriteProperty
屬性非空強校驗 Delegates.notNull()
Map值 映射到類屬性 map
-
-
inner
1、inner修飾的內部類可理解為java中的非靜態(tài)內部類,調用方式:
外部類().內部類().方法();
2、kotlin內部類默認為靜態(tài)的,理解為java中使用static修飾的內部類,調用方式:
外部類.內部類().方法();
3、如果需要在靜態(tài)內部類中使用外部類,可參考java中實現(xiàn)方式,在內部類中定義外部類弱引用,通過構造方法傳入外部類對象;
class InnerTest{ var a=5 class NotInner{ fun m1(i: Int):Int { // a=i 編譯不通過 return i + 1 } } //inner修飾過的內部類可以訪問外部內成員變量 inner class WithInner{ fun m2(i: Int):Int { a=i return a } } } fun main(args: Array<String>) { print(InnerTest.NotInner().m1(5)) //調用沒有被inner修飾過的內部類時,外部類不需要被實例化,類似與java中的靜態(tài)內部類 print(InnerTest().WithInner().m2(5)) //InnerTest類需要實例化才能調用被inner修飾過的內部類 }
-
解構Operator:
-
無date關鍵詞
//解構 方法體必須聲明為componentN() class Boy(var age: Int, var name: String){ operator fun component1()=age operator fun component2()=name } fun main(args: Array<String>) { var p1 = Person(19, "張三", "張二狗") var(age,name,lastname)=p1 }
-
有date關鍵字
//數(shù)據(jù)類中自帶了operator操作符,無需使用componentN()函數(shù) data class Person(val age: Int, val name: String, val lastName: String) fun main(args: Array<String>) { var (age, name) = Boy(15, "珠海") }
-
-
循環(huán)
for(i in 1..10){}//包括10 for(i in 1 until 10) //不包括10 for(i in 10 downTo 1) for(i in 1..10 step 2) //步進2 repeat(10){} //循環(huán)10次
//循環(huán)list
val testList = listOf<String>("a", "b", "c")
for ((index, value) in testList.withIndex()) {
print(index.toString()+value)
}
-
作用域函數(shù)
//返回lambda表達式結果 run{...} let{...} with(T){...} //返回上下文對象 apply{...} also{...}
-
Lambda閉包
val echo = { name: String -> print(name) } echo.invoke("張三")//invoke 調用,操作符重載 等價于下面一條語句 echo("王二")
- 高階函數(shù)(使用閉包函數(shù)作為參數(shù)傳入)
//高階函數(shù)
fun onlyif(age:Int,isDebug: Boolean, block: (a:Int) -> Unit) {
if (isDebug){
block(age)
}
}
fun main(args: Array<String>) {
val lam:(a:Int)->Unit//lambda聲明
lam={ print(it + 1)} //lambda表達式實現(xiàn)
onlyif(5,true,lam)//調用方法,傳入參數(shù)
}
- inline
通過該關鍵字來優(yōu)化代碼,編譯器將使用函數(shù)的定義體來替代函數(shù)調用語句,這種替代行為發(fā)生在編譯階段而非程序運行階段
fun plus(i: Int){
i += 1
}
//該段代碼會報Val cannot be reassigned的錯誤,因為kotlin是直接值傳遞,而java在值傳遞時候形參實際上是經過一次復制后的新值(內存地址改變,value不變)
-
sealed關鍵字
sealed class CompareResult{ object Less:CompareResult() { override fun toString(): String { return "小于" } } object More : CompareResult() { override fun toString(): String { return "大于" } } object Equals : CompareResult() { override fun toString(): String { return "相等" } } } //一旦使用密封類就要用完密封類中所有的子類,不然會編譯期報錯 fun check(cr: CompareResult):String { when (cr) { is CompareResult.Equals -> return cr.toString() is CompareResult.More -> return cr.toString() is CompareResult.Less -> return cr.toString() } } infix fun Int.vs(num: Int): CompareResult = if (this > num) { CompareResult.More }else if (this < num) { CompareResult.Less }else{ CompareResult.Equals } fun main(args: Array<String>) { print(7 vs 7) }
-
infix關鍵字
使用該關鍵字進行操作符重載
infix fun Int.vs(num: Int): CompareResult = //自定義了一個操作符vs 該操作符是以拓展函數(shù)的放法添加在目標類上的。 if (this > num) { CompareResult.More }else if (this < num) { CompareResult.Less }else{ CompareResult.Equals } fun main(args: Array<String>) { print(7 vs 7) }
-
enum枚舉
enum class AE(var age: Int, var lname: String) { A(14, "張三") { override fun a(a: Int): Int = a + 1 }, B(15, "王二") { override fun a(a: Int): Int = a + 2 }; //抽象方法,需要枚舉實例自己實現(xiàn)方法 abstract fun a(a: Int): Int //每個枚舉實例都默認實現(xiàn)該方法跟java枚舉一樣 fun b(str: String): String = str + this.lname } fun check(a: AE) { when (a) { AE.A -> print(a.lname) AE.B -> print(a.age) } } fun main(args: Array<String>) { check(AE.A) }
比較是否相等
java kotlin
a==b -> a ===b
a.equals(b) -> a==b-
集合
kotlin中的集合默認為只讀類型,可變類型是在不可變類型前添加Mutable
獲取一個新集合
var nums= mutableListOf<Int>()