員工考勤打卡時,如何避免非本人代替打卡?
794
2025-04-03
一、介紹
Kotlin 可以對一個類的屬性和函數進行擴展,且不需要繼承或使用 Decorator 模式。
擴展是一種靜態行為,對被擴展的類代碼本身不會造成任何影響。
二、擴展函數
擴展函數可以在已有類中添加新的函數,不會對原類做修改。
2.1 定義擴展函數
擴展可以用于自定義類,也可以用于比如List、String,以及Kotlin標準庫里的其他類。和繼承相似,擴展也能共享類行為,在你無法接觸某個類定義,或者某個類沒有使用open修飾符,導致你無法繼承它時,擴展就是增加類功能的最好選擇。
//定義School類的擴展函數 fun School.student():String{ return "$name-學習知識" }
School:表示函數的接收者,也就是函數擴展的對象
student:擴展函數的名稱
String:返回類型("$name-學習知識")
一、介紹
Kotlin 可以對一個類的屬性和函數進行擴展,且不需要繼承或使用 Decorator 模式。
擴展是一種靜態行為,對被擴展的類代碼本身不會造成任何影響。
二、擴展函數
擴展函數可以在已有類中添加新的函數,不會對原類做修改。
2.1 定義擴展函數
擴展可以用于自定義類,也可以用于比如List、String,以及Kotlin標準庫里的其他類。和繼承相似,擴展也能共享類行為,在你無法接觸某個類定義,或者某個類沒有使用open修飾符,導致你無法繼承它時,擴展就是增加類功能的最好選擇。
//定義School類的擴展函數 fun School.student():String{ return "$name-學習知識" }
School:表示函數的接收者,也就是函數擴展的對象
School:表示函數的接收者,也就是函數擴展的對象
student:擴展函數的名稱
student:擴展函數的名稱
String:返回類型("$name-學習知識")
String:返回類型("$name-學習知識")
其他的就和定義一般函數類似了。
2.1.1 定義School類
class School(var name:String){ //自帶函數 fun teacher():String{ return "$name-教書育人" } }
2.1.2 擴展函數
//定義School類的擴展函數 fun School.student():String{ return "$name-學習知識" } //定義String類的擴展函數 fun String.addSC():String{ return "$this-帥次" } fun main() { //School類原來的函數 println(School("超神學院").teacher())//超神學院-教書育人 //School類的擴展函數 println(School("超神學院").student())//超神學院-學習知識 //String類的擴展函數 println("Kotlin".addSC())//Kotlin-帥次 }
2.1.3 擴展函數支持范圍
擴展函數定義后在同一個包下可直接調用,在其他包下則需要導入定義的擴展函數。在extension包下定義的擴展函數,在classkotlin包中使用。
同一包下不能定義同名擴展函數。
import com.scc.kotlin.primary.extension.School import com.scc.kotlin.primary.extension.addSC import com.scc.kotlin.primary.extension.student fun main() { println(School("Class包下").student())//Class包下-學習知識 println("ClassKotlin".addSC())//ClassKotlin-帥次 }
在多個包下定義擴展函數addSC(),調用時:
2.1.4 定義超類(Any)擴展函數
因為Any是超類,所以它的擴展函數其他類也能直接使用。這個功能是真的強大。
//定義Any擴展函數 fun Any.eat(): Any { return this } fun main() { //因為Any是超類,所以它的擴展函數其他類也能直接使用 println("超類".eat())//超類 println(15.eat())//15 }
"超類".eat().addSC() 報錯
//報錯,因為addSC()函數是String類的擴展函數,Any類無法直接調用 //除非將 "超類".eat()的返回類型Any轉為String再調用。 "超類".eat().addSC()
這個時候我們該引入泛型擴展函數了。
2.1.5 泛型擴展函數
新的泛型擴展函數不僅可以支持任何類型的接收者,還保留了接收者的類型信息,使用泛型類型后,擴展函數能夠支持更多類型的接收者,適用范圍更廣了。
//定義泛型擴展函數 fun
String類型WaKa調用泛型擴展函數scww(),返回String類型調用String類型擴展函數addSC()
Int類型15調用泛型擴展函數scww(),返回Int類型調用apply{}函數
泛型擴展函數在Kotlin標準庫里隨處可見,例如apply函數,apply函數被定義成了泛型擴展函數,所以能支持任何類型。
public inline fun
三、擴展屬性
除了給類添加功能擴展函數外,你還可以給類定義擴展屬性。
擴展屬性允許定義在類或者kotlin文件中,不允許定義在函數中。初始化屬性因為屬性沒有后端字段(backing field),所以不允許被初始化,只能由顯式提供的 getter/setter 定義。
擴展屬性只能被聲明為 val。
//定義擴展屬性 //給String類添加一個擴展屬性,這個擴展屬性可以統計字符長度并加10。 val String.lengthSc get() = this.length.plus(10) //給School類添加個position屬性 val School.position get() = "${name}-高級中學" fun main() { println("一二三四五,上山打老虎".lengthSc)//21 println(School("新冠中學").position)//新冠中學-高級中學 }
四、可控類擴展
你也可以定義擴展函數用于可空類型,在可空類型上定義擴展函數,你就可以直接在擴展函數體內解決可能出現的空值問題。
//可空類擴展 //當String為null時打印四大皆空-default fun String?.nullWithDefault(default: String) { println(this ?: "四大皆空-$default") } //當School為null時,打印default-學校沒了 fun School?.dropOut(default: String) { println(this ?: "$default-學校沒了") } fun main() { var str: String? = null str.nullWithDefault("空空")//四大皆空-空空 str = "數據已到" str.nullWithDefault("空空")//數據已到 var school: School? = null school.dropOut("沒得名字")//沒得名字-學校沒了 school = School("帥次學院") school.dropOut("默認退學")//com.scc.kotlin.primary.extension.School@19dfb72a }
infix 關鍵字
infix關鍵字適用于有單個參數的擴展和類函數,可以讓你以更簡潔的語法調用函數,如果一個函數定義使用了infix關鍵字,那么調用它時,接收者和函數之間的點操作以及參數的一對括號都可以不要。 (類似 to 函數)
//infix關鍵字 infix fun String?.nullInfixDefault(default: String){ println(this ?: "Infix-$default") } fun main() { str = null str nullInfixDefault "空值" //Infix-空值 str = "不空" str nullInfixDefault "空值" //不空 //這個就類似mapOf mapOf("Key" to "Value") }
to函數源碼
泛型拓展函數、前面加了infix關鍵字
public infix fun A.to(that: B): Pair = Pair(this, that)
Kotlin標準庫中的擴展函數:Kotlin標準庫提供的很多功能都是通過擴展函數和擴展屬性來實現的,包含類擴展的標準庫文件通常都是以類名加s后綴來命名的,例如Sequences.kt,Ranges.kt,Maps.kt。
五、定義擴展文件
擴展函數需要在多個文件里面使用,可以將它定義在單獨的文件,然后import。
5.1 定義擴展文件
package com.scc.kotlin.primary.extension //定義擴展文件 fun
5.2 使用
同一包名下的文件調用scFile():
fun main() { str.scFile()//來自ScFile的問候 }
其他包下的文件調用scFile():
import com.scc.kotlin.primary.extension.scFile fun main() { var userInfo4 = UserInfo4() userInfo4.scFile()//來自ScFile的問候 }
5.3 重命名擴展(import文件別名)
import com.scc.kotlin.primary.extension.scFile as scAliasFile fun main() { var userInfo4 = UserInfo4() userInfo4.scAliasFile()//使用新定義的別名,來自ScFile的問候 // userInfo4.scFile()//無法使用,報錯 }
六、()->Unit 和 引用類型.()->Unit
package com.scc.kotlin.primary.extension //() -> Unit:普通匿名函數 fun String.doAnonymous(anonymous:() -> Unit):String{ anonymous() return "$this,AnonymousN" } //String.() -> Unit:匿名函數內部this指向一個String對象,隱式調用 fun String.doAnonymousString(anonymous: String.() -> Unit) :String{ println(this) anonymous() return this } //這里使用的泛型匿名函數,使用其內部this fun
DSL
使用這樣的編程范式,就可以寫出業界知名的“領域特定語言”(DSL),一種API編程范式,暴露接收者的函數和特性,以便于使用你定義的lambda表達式來讀取和配置它們。
Android android studio Kotlin
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。