Object Expressions and Declarations

對象表達式和申明:
    有些時候咱們須要建立一個輕量修改的類,沒有明確申明一個新的超類,Java處理這種狀況是用一個異步內部類實現,kotlin則用對象表達式和對象申明的概念來實現。
    
    對象表達式:
        建立一個繼承某些類的異步類對象,咱們這樣寫:
        
```
window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }html

    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
})
```
若是超類有一個構造函數,那麼必須傳遞一個合適構造參數,某些超類應該在冒號以後寫成爲一個逗號分開的列表
```
open class A(x: Int) {
    public open val y: Int = x
}java

interface B {...}異步

val ab: A = object : A(1), B {
    override val y = 15
}
```
若是,某些狀況下,咱們須要僅僅一個對象,沒有複雜的超類,咱們能夠簡單的寫成這樣:
```
fun foo() {
    val adHoc = object {
        var x: Int = 0
        var y: Int = 0
    }
    print(adHoc.x + adHoc.y)
}
```
這個有點像Java中的匿名類,並把索引給參數adHoc,裏面定義了兩個屬性值,經過.操做進行取值。ide

注意:異步對象能夠在僅僅是一個本地私有申明的時候用來作看成一個類,若是你使用一個異步對象做爲公共函數返回值的類型或者公共屬性的返回類型,那麼這個實際類型
式函數或者屬性將被申明這個異步對象的超類或者返回Any,若是你沒有申明任何超類,添加在異步對象的成員將不可被訪問
```
class C {
    // Private function, so the return type is the anonymous object type
    private fun foo() = object {
        val x: String = "x"
    }函數

    // Public function, so the return type is Any
    fun publicFoo() = object {
        val x: String = "x"
    }htm

    fun bar() {
        val x1 = foo().x        // Works
        val x2 = publicFoo().x  // ERROR: Unresolved reference 'x'
    }
}
```
僅僅想Java的異步內部類,代碼在對象表達式中能夠訪問外部塊(不像java,這沒有限制爲final變量)
```
fun countClicks(window: JComponent) {
    var clickCount = 0
    var enterCount = 0對象

    window.addMouseListener(object : MouseAdapter() {
        override fun mouseClicked(e: MouseEvent) {
            clickCount++
        }繼承

        override fun mouseEntered(e: MouseEvent) {
            enterCount++
        }
    })
    // ...
}
```
    對象申明:
    
    單例模式是一個很是有用的模式,而且Kotlin能夠很容易把他申明單例模式,
```
object DataProviderManager {
    fun registerDataProvider(provider: DataProvider) {
        // ...
    }索引

    val allDataProviders: Collection<DataProvider>
        get() = // ...
}
```
這個叫作對象申明,而且他老是有一個object關鍵詞在名字後面。僅僅像一個變量申明,一個對象申明不是一個表達式,沒有可能被用到在約定申明的右手邊,聯繫到對象,咱們直接用他的名字
```
DataProviderManager.registerDataProvider(...)
```
如此對象擁有超類
```
object DefaultListener : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }接口

    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
}
```
標記:對象申明沒有本地,可是他們能夠嵌套進其餘對象申明或者非內部類


同伴對象:
    在類中的對象申明能夠用companion標記
```
class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}
```
同伴對象的成員能夠被調用經過使用簡單的類名字當作修飾
```
val instance = MyClass.create()
```
同伴對象的名字能夠被省略,在Companion將被使用的例子中
```
class MyClass {
    companion object {
    }
}

val x = MyClass.Companion
```
記錄:即便同伴對象的成員看起來像靜態成員,在運行時,這些真實對象的陳成員仍然存在,而且可能好比繼承接口,:
```
interface Factory<T> {
    fun create(): T
}


class MyClass {
    companion object : Factory<MyClass> {
        override fun create(): MyClass = MyClass()
    }
}
```
然而在JVM中你能夠擁有同伴對象的成員當作靜態方法和域生產。若是你使用@JvmtSatic,[Java interoperability](http://kotlinlang.org/docs/reference/java-to-kotlin-interop.html#static-fields)

在對象表達式和申明中的語義區別: 這有一個重點語義區別:     一、對象表達式能夠在須要使用的時候被當即執行     二、對象申明在咱們第一次訪問的時候進行延遲申明     三、一個同伴對象噹噹前類被加載被初始化,匹配的是Java靜態初始化語義

相關文章
相關標籤/搜索