Kotlin彙總5-內部類,枚舉類,對象,代理

1. 內部類

內部類是內嵌類在kotlin是不一樣的,比如下面是內嵌類

class Outer {
    private val bar: Int = 1
    class Nested {
        fun foo() = 2
    }
}

val demo = Outer.Nested().foo() // == 2

下面是內部類

class Outer {
    private val bar: Int = 1
    inner class Inner {
        fun foo() = bar
    }
}

val demo = Outer().Inner().foo() // == 1

還可以使用object作爲內部類

window.addMouseListener(object: MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }

    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
})

也可以使用lambda表達式

val listener = ActionListener { println("clicked") }

2. 枚舉類

kotlin的枚舉類和java基本一樣

enum class ProtocolState {
    WAITING {
        override fun signal() = TALKING
    },

    TALKING {
        override fun signal() = WAITING
    };

    abstract fun signal(): ProtocolState
}

3.對象

有些時候我們想創建一個輕微修改的類對象,但是又不想創建一個新類去繼承,那麼這個時候就可以用object來修飾。

window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }

    override fun mouseEntered(e: MouseEvent) {
        // ...
    }
})

其實說白了,object就是匿名類的意思

open class A(x: Int) {
    public open val y: Int = x
}

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)
}

需要注意:匿名對象只能用戶本地聲明或者private聲明,看下面例子

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"
    }

    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++
        }
    })
    // ...
}

還可以作爲單例模式使用

object DataProviderManager {
    fun registerDataProvider(provider: DataProvider) {
        // ...
    }

    val allDataProviders: Collection<DataProvider>
        get() = // ...
}

DataProviderManager.registerDataProvider(...)

還可以使用companion關鍵字修飾,變成Companion Objects

class MyClass {
    companion object Factory {
        fun create(): MyClass = MyClass()
    }
}

val instance = MyClass.create()
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()
    }
}

感覺object這個東西很靈活,用起來很方便。

4. 代理

在Java中,有時候我們需要代理某個對象的方法,比如

class A{
    void print(){
        System.out.println();
    }
}

class B{
    A a;
    void print(){
        a.print();
    }
}

但是在kotlin,只要如下寫:

interface Base {
    fun print()
}

class BaseImpl(val x: Int) : Base {
    override fun print() { print(x) }
}

class Derived(b: Base) : Base by b //把b對象的方法交給Derived代理,所以代理也要慎用

fun main(args: Array<String>) {
    val b = BaseImpl(10)
    Derived(b).print() // prints 10
}

當然屬性也是可以代理的,可以回到之前寫的看看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章