Kotlin 4 构造,对象,修饰符,关键字,委托
注:當(dāng)前文檔為Kotlin自學(xué)總結(jié),若什么地方含義模糊不清,敬請(qǐng)指教,謝謝:-)。
目錄:- 構(gòu)造函數(shù)- 對(duì)象- 匿名對(duì)象- 對(duì)象聲明- 對(duì)象表達(dá)式和對(duì)象聲明之間的語(yǔ)義差異- 修飾符- 關(guān)鍵字- 委托- 類委托- 屬性委托- 要求- 延遲性- 觀察者模式- 屬性映射- 局部委托 復(fù)制代碼構(gòu)造函數(shù) - 一個(gè)主構(gòu)造多個(gè)次構(gòu)造,主構(gòu)造函數(shù)的所有的參數(shù)都有默認(rèn)值
-  主構(gòu)造:(類聲明之后) //默認(rèn)類聲明 + 主構(gòu)造class ClazzName public constructor{}class ClazzName public @Inject constructor(val/var params1 : type = defultValue){//constructor可省略,有注解時(shí)必須存在//public 為可見性修飾符init {//init -> 初始化代碼塊,主構(gòu)造的參數(shù)可以在初始化代碼塊使用}} 復(fù)制代碼
-  次構(gòu)造:委托或間接委托給主構(gòu)造,需要 this 關(guān)鍵字(也可有constructor前綴) class Person(val name: String) {//類聲明 + 主構(gòu)造constructor(name: String, parent: Person) : this(name) {//次構(gòu)造,相當(dāng)于添加參數(shù)或重新賦值name//... ...}} 復(fù)制代碼
-  創(chuàng)建一般實(shí)例 - 沒有new 關(guān)鍵字 val invoice = Invoice()val customer = Customer("Joe Smith") //創(chuàng)建使用匿名對(duì)象,對(duì)象聲明,單例請(qǐng)查看Kotlin-4.md 復(fù)制代碼
對(duì)象
一般對(duì)象的創(chuàng)建方式使用構(gòu)造函數(shù)傳參創(chuàng)建.
1. 匿名對(duì)象
一般匿名對(duì)象的使用
window.addMouseListener(object : MouseAdapter() {override fun mouseClicked(e: MouseEvent) {// ……} }) 復(fù)制代碼多個(gè)繼承或?qū)崿F(xiàn)并且需要傳參的匿名對(duì)象
open class A(x: Int) {public open val y: Int = x }interface B {……}val ab: A = object : A(1), B {override val y = 15 } 復(fù)制代碼沒有繼承或?qū)崿F(xiàn)的匿名對(duì)象創(chuàng)建
fun foo() {val adHoc = object {var x: Int = 0var y: Int = 0}print(adHoc.x + adHoc.y) } 復(fù)制代碼公有函數(shù)返回值為匿名對(duì)象時(shí),類型為Any,將不能訪問(wèn)匿名對(duì)象的成員.
class C {// 私有函數(shù),所以其返回類型是匿名對(duì)象類型private fun foo() = object {val x: String = "x"}// 公有函數(shù),所以其返回類型是 Anyfun publicFoo() = object {val x: String = "x"}fun bar() {val x1 = foo().x // 沒問(wèn)題val x2 = publicFoo().x // 錯(cuò)誤:未能解析的引用“x”} } 復(fù)制代碼對(duì)象聲明
對(duì)象聲明只能在其他對(duì)象聲明或非內(nèi)部類中.
//有繼承的單例對(duì)象聲明 object DataProviderManager : Parent() {fun registerDataProvider(provider: DataProvider) {// ……}val allDataProviders: Collection<DataProvider>get() = // …… }//直接調(diào)用 DataProviderManager.registerDataProvider(....) 復(fù)制代碼對(duì)象表達(dá)式和對(duì)象聲明之間的語(yǔ)義差異
對(duì)象表達(dá)式和對(duì)象聲明之間有一個(gè)重要的語(yǔ)義差別:
- 對(duì)象表達(dá)式是在使用他們的地方立即執(zhí)行(及初始化)的 - 對(duì)象聲明是在第一次被訪問(wèn)到時(shí)延遲初始化的 - 伴生對(duì)象的初始化是在相應(yīng)的類被加載(解析)時(shí),與 Java 靜態(tài)初始化器的語(yǔ)義相匹配 復(fù)制代碼修飾符
-  val和var val 只讀;var 可變.(var默認(rèn)創(chuàng)建getter,setter; val 默認(rèn)創(chuàng)建 getter) 復(fù)制代碼
-  可見性修飾符 
-  internal →代替→ default,意味著該成員只在相同模塊內(nèi)可見。更具體地說(shuō), 一個(gè)模塊是編譯在一起的一套 Kotlin 文件: 一個(gè) IntelliJ IDEA 模塊;一個(gè) Maven 或者 Gradle 項(xiàng)目;一次 <kotlinc> Ant 任務(wù)執(zhí)行所編譯的一套文件。 復(fù)制代碼
-  局部變量、函數(shù)和類不能有可見性修飾符。 
關(guān)鍵字
-  this -  在類的成員中,this 指的是該類的當(dāng)前對(duì)象. 
-  在擴(kuò)展函數(shù)或者帶接收者的函數(shù)字面值中, this 表示在"."左側(cè)傳遞的接收者參數(shù)。 class A { // 隱式標(biāo)簽 @Ainner class B { // 隱式標(biāo)簽 @Bfun Int.foo() { // 隱式標(biāo)簽 @fooval a = this@A // A 的 thisval b = this@B // B 的 thisval c = this // foo() 的接收者,一個(gè) Intval c1 = this@foo // foo() 的接收者,一個(gè) Intval funLit = lambda@ fun String.() {val d = this // funLit 的接收者}val funLit2 = { s: String ->// foo() 的接收者,因?yàn)樗?lambda 表達(dá)式// 沒有任何接收者val d1 = this}}}} 復(fù)制代碼
 
-  
-  abstract 抽象 
-  companion → static(不存在此關(guān)鍵字) 伴生對(duì)象 -  類沒有靜態(tài)方法。在大多數(shù)情況下,它建議簡(jiǎn)單地使用包級(jí)函數(shù)。 
-  需要訪問(wèn)其他類內(nèi)部的函數(shù),可以把它寫成該類內(nèi)對(duì)象聲明中的一員。 class MyClass {companion object Factory { //Factory名稱可以省略fun create(): MyClass = MyClass()}}//其他類中調(diào)用需要val instance = MyClass.create()//名稱省略后val x = MyClass.Companion 復(fù)制代碼
 
-  
-  const 編譯時(shí)常量 請(qǐng)查看Kotlin-3.md 編譯時(shí)常量?jī)?nèi)容 復(fù)制代碼
-  lateinit 延遲初始化屬性使用 -  使用字段可以避免編譯時(shí)空檢查 
-  只能與var配合使用 
-  屬性類型不能為空或原生類型 
-  可以在單元測(cè)試的@setUp函數(shù)中初始化; 
-  初始化前訪問(wèn)屬性會(huì)拋出"被訪問(wèn)且沒有初始化"的異常. public class MyTest {lateinit var subject: TestSubject@SetUp fun setup() {subject = TestSubject()}@Test fun test() {subject.method() // 直接解引用}} 復(fù)制代碼
 
-  
委托
類委托
格式:
class A{fun aa()fun bb()... }class A1:A{override fun aa(){...}override fun bb(){...}... }class ClazzName(a:A):A by a{... }//使用 clazzName(A1()).aa() 復(fù)制代碼某個(gè)類通過(guò)關(guān)鍵字by,使用委托參數(shù)的方式、繼承的格式,調(diào)用自身沒有但該參數(shù)所在類標(biāo)注的基類存在的所有公有函數(shù)的形式,叫做類委托.
原理:by 語(yǔ)句會(huì)將對(duì)應(yīng)的委托對(duì)象進(jìn)行內(nèi)部存儲(chǔ),編譯器將生成轉(zhuǎn)發(fā)給該對(duì)象的所有標(biāo)注基類的方法。
interface Base {fun print() }class BaseImpl(val x: Int) : Base {override fun print() { print(x) } }class Derived(b: Base) : Base by b //Base為BaseImpl b的基類fun main(args: Array<String>) {val b = BaseImpl(10)Derived(b).print() // 輸出 10 } 復(fù)制代碼委托屬性
使用**by關(guān)鍵字,將屬性的getter、setter委托給函數(shù)或某個(gè)類的operator** 函數(shù),
屬性委托要求
對(duì)于一個(gè)只讀屬性(即 val 聲明的),委托必須提供一個(gè)名為 getValue 的函數(shù),該函數(shù)接受以下參數(shù):
thisRef —— 必須與 屬性所有者 類型(對(duì)于擴(kuò)展屬性——指被擴(kuò)展的類型)相同或者是它的超類型, property —— 必須是類型 KProperty<*> 或其超類型, 這個(gè)函數(shù)必須返回與屬性相同的類型(或其子類型)。
對(duì)于一個(gè)可變屬性(即 var 聲明的),委托必須額外提供一個(gè)名為 setValue 的函數(shù),該函數(shù)接受以下參數(shù):
thisRef —— 同 getValue(), property —— 同 getValue(), new value —— 必須和屬性同類型或者是它的超類型。 getValue() 或/和 setValue() 函數(shù)可以通過(guò)委托類的成員函數(shù)提供或者由擴(kuò)展函數(shù)提供。 當(dāng)你需要委托屬性到原本未提供的這些函數(shù)的對(duì)象時(shí)后者會(huì)更便利。 兩函數(shù)都需要用 operator 關(guān)鍵字來(lái)進(jìn)行標(biāo)記。
委托類可以實(shí)現(xiàn)包含所需 operator 方法的 ReadOnlyProperty 或 ReadWriteProperty 接口之一。 這倆接口是在 Kotlin 標(biāo)準(zhǔn)庫(kù)中聲明的:
interface ReadOnlyProperty<in R, out T> {operator fun getValue(thisRef: R, property: KProperty<*>): T }interface ReadWriteProperty<in R, T> {operator fun getValue(thisRef: R, property: KProperty<*>): Toperator fun setValue(thisRef: R, property: KProperty<*>, value: T) } 復(fù)制代碼延遲性
延遲: (lazy() 是接受一個(gè) lambda 并返回一個(gè) Lazy 實(shí)例的函數(shù),返回的實(shí)例可以作為實(shí)現(xiàn)延遲屬性的委托.)第一次調(diào)用 get() 會(huì)執(zhí)行已傳遞給 lazy() 的 lamda 表達(dá)式并記錄結(jié)果, 后續(xù)調(diào)用 get() 只是返回記錄的結(jié)果。
延遲是具有同步鎖線程安全的,默認(rèn) LazyThreadSafetyMode.PUBLICATION傳入lazy(),使用 LazyThreadSafetyMode.NONE 模式, 它不會(huì)有任何線程安全的保證和相關(guān)的開銷。
val lazyValue: String by lazy {println("computed!")"Hello" }fun main(args: Array<String>) {println(lazyValue)println(lazyValue) } //輸出內(nèi)容 //computed! //Hello //Hello 復(fù)制代碼委托的觀察者模式
Delegates.observable()和Delegates.vetoable()
Delegates.observable() 接受兩個(gè)參數(shù):初始值和修改時(shí)處理程序(handler)。 每當(dāng)我們給屬性賦值時(shí)會(huì)調(diào)用該處理程序(在賦值后執(zhí)行)。它有三個(gè) 參數(shù):被賦值的屬性、舊值和新值;
import kotlin.properties.Delegatesclass User {var name: String by Delegates.observable("<no name>") {//初始值prop, old, new -> //被賦值的屬性、舊值和新值println("$old -> $new")} }fun main(args: Array<String>) {val user = User()user.name = "first"user.name = "second" }//打印內(nèi)容為 //<no name> -> first //first -> second 復(fù)制代碼Delegates.vetoable()可以截獲一個(gè)賦值并“否決”它,在屬性被賦新值生效之前會(huì)調(diào)用傳遞給 vetoable 的處理程序。
屬性存儲(chǔ)到映射 - 在一個(gè)映射(map)里存儲(chǔ)屬性的值。
class User(val map: Map<String, Any?>) {val name: String by mapval age: Int by map }val user = User(mapOf("name" to "John Doe","age" to 25 ))println(user.name) // Prints "John Doe" println(user.age) // Prints 25 復(fù)制代碼val -> Map, var -> MutableMap
局部委托點(diǎn)擊此處
本文參考自 Kotlin語(yǔ)言中心站
轉(zhuǎn)載于:https://juejin.im/post/5a32177e6fb9a0450167f9f5
總結(jié)
以上是生活随笔為你收集整理的Kotlin 4 构造,对象,修饰符,关键字,委托的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
 
                            
                        - 上一篇: 使用nginx代理跨域,使用nginx代
- 下一篇: 【下一代核心技术DevOps】:(三)私
