본문

171212(화) - Kotlin docs (Object Expressions and Declarations)

Kotlin docs 


Object Expressions and Declarations


- 때로는 새로운 class를 explicitly declaring 하지않고 slight modification한 object를 만들어야 한다.

- Java는 anonymous inner classes로 처리

- Kotlin은 object expressions and object declarations concept로 slightly generalizes 한다.


Object expressions

- some type으로부터 inherits한 anonymous class를 create하기 위해서 다음과 같이 작성

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

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

- supertype에  constructor가 있으면, 적절한 constructor parameters가 있어야 한다.

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

interface B {...}

val ab: A = object : A(1), B {
    override val y = 15
}

- supertype이 없고 just an object 라면

fun foo() {
    val adHoc = object {
        var x: Int = 0
        var y: Int = 0
    }
    print(adHoc.x + adHoc.y)
}

- anonymous objects는 only local and private delarations 로만 사용될 수 있다.

- anonymous objects를 public function or property type으로 사용하는 경우 실제 type은 super type이거나 super 유형이 선언되지 않은경우 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"
    }

    fun bar() {
        val x1 = foo().x        // Works
        val x2 = publicFoo().x  // ERROR: Unresolved reference 'x'
    }
}

- java anonymous inner classes와 마찬가지로 enclosing scope에 접근 가능하다.

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 declarations

- kotlin에서의 singleton은 object declaration이라고 부른다.

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

    val allDataProviders: Collection<DataProvider>
        get() = // ...
}
object DefaultListener : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) {
        // ...
    }

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


Companion Objects

- class 내부의 object 선언

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

- companion object 의 이름 생략 가능

class MyClass {
    companion object {
    }
}

val x = MyClass.Companion


- companion object가 static members처럼 보일지 모르나, runtime에 여전히 instance members의 real object이며 interface도 implement 가능하다.

interface Factory<T> {
    fun create(): T
}


class MyClass {
    companion object : Factory<MyClass> {
        override fun create(): MyClass = MyClass()
    }
}
val instance = MyClass.create()

@JvmStatic을 사용하면 JVM상에서 companion object를 real static methods and field로 사용 가능하다.

 Java interoperability



Semantic difference between object expressions and delarations

- object expressions는 used되는 곳에서 immediately executed and initialized 된다.

- object declarations는 first time accessed에서 lazily initialized

- companion object는 해당 class가 loaded될 때 초기화 되고 java static initializer semantics와 일치

공유

댓글