"object"關(guān)鍵字

object關(guān)鍵字在多種情況下出現(xiàn),其核心理念:將聲明一個類和創(chuàng)建一個實例結(jié)合起來。class

使用場景:

1、對象聲明是定義單例的一種方式。

2、伴生對象可以持有工廠方法和其他與這個類有關(guān)。但在調(diào)用時并不依賴類實例的方法。他們的成員可以通過類名來訪問。

3、對象表達(dá)式用來代替Java的匿名內(nèi)部類。

1.1、對象聲明:創(chuàng)建單例易如反掌

Kotlin通過使用對象聲明功能將類的聲明與該類的單一實例聲明結(jié)合到了一起。

object? Payroll{

?????? val allEmployees=arrayListOf<Person>()

??????? fun calculateSalary(){

???????????????? for(person in allEmployees){...}

??????? }

}

對象聲明唯一不允許的就是構(gòu)造方法,包括朱構(gòu)造方法和從構(gòu)造方法。

調(diào)用:Payroll.allEmployees.add(Person(...))

Payroll.calculateSalary()

對象聲明同樣可以繼承自類和接口。通常在你使用的框架需要趨勢線一個接口,但是你的實現(xiàn)并不包含任何狀態(tài)的時候很有用。例如Comparator接口。

1.2、伴生對象:工廠方法和靜態(tài)成員的地盤

Kotlin中的類不能擁有靜態(tài)成員,它沒有static關(guān)鍵字。包級別函數(shù)(多頂層函數(shù)) 可以替代 Java靜態(tài)的方法 ;對象聲明 可以替代? Java靜態(tài)方法 和 靜態(tài)字段。頂層函數(shù)不能訪問類的private成員,可以使用 那個類中的對象聲明的成員。


在類中定義的對象之一可以使用一個特殊的關(guān)鍵字來標(biāo)記:companion 。這樣可以直接通過容器類名稱來訪問這個對象的方法和屬性。

class?? A {

????????? companion? object {

????????????????? fun bar() = println(" Companion? object?? called ")

???????? }

}

調(diào)用:A.bar()?


class User {???? //一般我們會用多個構(gòu)造來創(chuàng)建不同的對象

????? val? nickname : String

????? constructor(email:String){

???????????????? nickname=email.substringBefore('@')

?????? }

?????? constructor(facebookAccountId:Int){

????????????????? nickname=getFacebookName(facebookAccountId)

??????? }

??????? private fun getFacebookName(facebookAccountId: Int): String {

???????????????? return "facebookUserName"

? ???? }

}

//使用工廠方法來代替從構(gòu)造方法

class Userprivate constructor(val nickname : String){

private val niname ="bob" // 在companion object 內(nèi)無法訪問

? ? companion object {

?????????? ? fun newSubscribingUser(email: String) = User(email.substringBefore('@'))

???????????? fun newFacebookUser(accountId : Int) = User(getFacebookName(accountId))

???????????? private fun getFacebookName(accountId: Int): String {

??????????????????????? return "facebookUserName"

? ? ? ?????? }

??? }

}


優(yōu)點:工廠方法可以返回聲明這個方法的類的子類(如newSubscribingUser,newFacebookUser類都是User的子類)

缺點:如果要擴(kuò)展這樣的類,使用多構(gòu)造方法更好,因為伴生對象成員在子類中不能被重寫。

1.3、作為普通對象使用的伴生對象

1.3.1、聲明一個命名伴生對象

class Person(val name :String){

???????? companion object Loader{????? //聲明一個命名伴生對象

???????????????? fun fromJson(jsonText:String):Person = Person(jsonText)

????????? }

}

1.3.2、在伴生對象中實現(xiàn)接口

interface JSONFactory{

??????? fun fromJSON(jsonText: String):T

}

class Person(val name :String){

?????????? companion object : JSONFactory{

???????????????????? override fun fromJSON(jsonText: String): Person { //實現(xiàn)接口的伴生對象

????????????????????????????? return Person(jsonText)

????????????????????? }

??????????? }

}

1.3.3、伴生對象的擴(kuò)展

class? Person(val firstName : String,val lastName :String){

???????? companion?? object {?? //空的伴生對象

??????? }

}

fun? Person.Companion.fromJson(json;String) :Person{} //聲明擴(kuò)展函數(shù)

val? p=Person.fromJson(json)? //調(diào)用

1.4、對象表達(dá)式:改變寫法的匿名內(nèi)部類

object關(guān)鍵字還可以用來聲明匿名對象。

window.addMouseListener (

?????????? object:MouseAdapter(){?? //聲明繼承MouseAdapter的匿名對象

?????????????????? override? fun? mouseClicked(e:MouseEvent){}

?????????????????? override? fun? mouseEntered(e:MouseEvent){}

????????? }

)

與對象聲明不同,匿名對象不是單例的。每次對象表達(dá)式被執(zhí)行都會創(chuàng)建一個新的對象實例

擴(kuò)展函數(shù)我的通俗理解:類名.方法名? 的方法 稱之為擴(kuò)展函數(shù)。

fun? countClicks(window:Window){

??????? var clickCount= 0

???????? window.addMouseListener(

??????????????? object:MouseAdapter(){?? //聲明繼承MouseAdapter的匿名對象

???????????????????? override? fun? mouseClicked(e:MouseEvent){clickCount ++ } //匿名對象訪問局部變量

????????????????????? override? fun? mouseEntered(e:MouseEvent){}

??????????? }

????? )

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容