本文是對<<Kotlin in Action>>
的學習筆記,若是須要運行相應的代碼能夠訪問在線環境 try.kotlinlang.org,這部分的思惟導圖爲: 框架
在平時的開發中,咱們每每會使用許多的xxBean
對象用做數據容器,而在定義這些對象時,通常會重寫它的如下三個方法:函數
equals
:用來比較實例hashCode
:用來做爲例如HashMap
這種基於哈希容器的類toString
:用來爲類生成按聲明順序排列的全部字段的字符串表達形式在Kotlin
中,只須要爲你的類添加data
關鍵字,以上這些必要的方法就會自動生成好,例以下面的例子,咱們演示了以上三個方法的做用: 學習
equals
和hashCode
方法會將全部在主構造方法中聲明的屬性歸入考慮:設計
equals
方法會檢測全部的屬性的值是否相等hashCode
方法會返回一個根據全部屬性生成的哈希值在設計數據類時,應當儘可能只使用只讀的屬性,讓數據類的實例不可變,由於若是不這樣,被用做鍵的對象在加入HashMap
或者相似容器後被修改了,容器會進入一種無效的狀態。3d
爲了讓使用不可變對象變得容易,Kotlin
編譯器爲它們生成了copy
方法,並在copy
的同時修改某些屬性的值,copy
出來的副本有着單獨的聲明週期並且不會影響代碼中引用原始實例的位置,使用方法以下: code
當咱們須要向一個類添加一些行爲時,通常有兩種作法:cdn
而Kotlin
將委託做爲一個語言級別的功能作了頭等支持。不管何時實現一個接口,你均可以使用by
關鍵字 將接口的實現委託到另外一個對象;當須要修改某些方法的行爲時,能夠重寫它們,這樣你的方法就會被調用而不是使用生成的方法,能夠保留感到滿意的委託給內部的實例中的默認實現。 對象
object
關鍵字在多種狀況下出現,它的核心理念爲:這個關鍵字 定義一個類並同時建立一個實例,下面咱們介紹它的三個應用場景:blog
Java
的匿名內部類。在Java
中,單例模式一般是使用private
構造方法,而且用靜態字段來持有這個類僅有的實例。繼承
而在Kotlin
中,經過使用對象聲明功能,將類聲明與該類的單一實例聲明結合到了一塊兒。
object
關鍵字引入,一個對象聲明能夠很是高效地以一句話來定義一個類和一個該類的變量。.
字符的方式來調用方法和訪問屬性。對象聲明能夠繼承自類和接口,這一般在你使用的框架須要去實現一個接口,可是你的實現不包含任何狀態的時候頗有用。
在類中使用對象聲明時,這樣的對象一樣只有一個單一實例:它們在每一個容器類的實例中具備相同的實例。
運行結果爲:若是要在Java
中使用Kotlin
中的聲明對象,能夠經過訪問靜態的INSTANCE
字段:
Kotlin
的類不能擁有靜態成員,做爲替代,Kotlin
依賴包級別函數(在大多數情形下可以替代Java
的靜態方法)和對象聲明(在其餘狀況下替代Java
的靜態方法,同時還包括靜態字段),在大多數狀況下,推薦使用頂層函數,可是頂層函數不能訪問類的private
變量。
所以,若是你須要寫一個 在沒有類實例的狀況下 調用可是須要 訪問類內部的函數,能夠將其寫成那個類中的 對象聲明的成員。
在類中定義的對象之一可使用一個特殊的關鍵字來標記 companion,若是這樣作,就得到了直接 經過容器類名稱來訪問這個對象的方法和屬性的能力,再也不須要顯示地指明對象的名稱,下面是一個基礎的示例:
運行的結果爲:下面是使用伴生對象來實現工廠方法的例子:
伴生對象是一個聲明在類中的普通對象,它能夠有名字,實現一個接口或者有擴展函數或屬性。假設咱們須要在對象和JSON
之間進行序列化和反序列化,能夠將序列化的邏輯放在伴生對象中。
Person
類)來引用伴生對象,因此沒必要關心它的名字,若是省略了伴生對象的名字,默認的名字將會分配爲
Companion
。
就像其它對象聲明同樣,伴生對象也能夠實現接口,能夠將包含它的類的名字當作實現了該接口的對象實例來使用。
運行結果爲:在 Kotlin 知識梳理(2) - 函數的定義與調用 中,咱們介紹了經過擴展函數,能夠經過代碼庫中其它地方定義類實例調用的方法,可是若是你須要定義能夠經過 類自身調用的方法,就像伴生對象方法或者Java
靜態方法該怎麼辦呢?
舉例來講,若是類有一個伴生對象,能夠經過在其上定義擴展函數來作到這一點,即類C
有一個伴生對象,而且在C.Companion
上定義了一個擴展函數func
,則能夠經過C.fun()
來調用它。
下面,咱們爲Person
類的伴生對象定義一個擴展函數:
當調用toJson
就像是它是一個伴生對象定義的方法同樣,可是實際上它是做爲擴展函數在外部定義的。而爲了可以爲你的類定義擴展,必須在其中聲明一個對象,即便是空的。
object
關鍵字不只可以用來代表單例式的對象,還能用來聲明 匿名對象,它替代了Java
中匿名內部類的用法。例如,讓咱們來看看怎樣將一個典型的匿名內部類用法轉換成Kotlin
:
除了去掉對象的名字外,語法與對象聲明相同的。對象表達式聲明瞭一個類並建立了該類的一個實例,可是沒有給這個類或是實例分配一個名字。一般來講,它們都是不須要名字的,由於你會將這個對象用做一個函數調用的參數。若是你須要給對象分配一個名字,能夠將其存儲到一個變量中:
Java
的匿名類同樣,在對象表達式中的代碼能夠訪問建立它的函數中的變量,可是與Java
不一樣,訪問並被限制在final
變量,還能夠在對象表達式中修改變量的值。
運行結果爲: