객체 표현식과 객체 선언

4007 단어
때때로, 우리는 어떤 클래스에 대해 경미한 변화를 한 클래스의 대상을 만들어야 하며, 이를 위해 새로운 하위 클래스를 명확하게 설명하지 않아도 된다.Kotlin은 객체 표현식과 객체 선언을 사용하여 이러한 상황을 처리합니다.

객체 표현식


다음과 같이 특정 유형의 익명 클래스를 상속하는 객체를 만듭니다.
window.addMouseListener(object : MouseAdapter() {
    override fun mouseClicked(e: MouseEvent) { /*……*/ }

    override fun mouseEntered(e: MouseEvent) { /*……*/ }
})

이쪽 Object: MouseAdapter () 대상을 계승합니다. 이 대상은interface 괄호 안에 interface를 실현하는 방법이 있습니다.
어떤 공급류를 계승할 필요가 없음,interface로
httpClient.newCall(request).enqueue(object : Callback {
            //url、port      
            override fun onFailure(call: Call, e: IOException) {
            }

이쪽은 Object:인터페이스 있음:Callback 사용 가능
만약 초유형에 구조 함수가 있다면, 반드시 적당한 구조 함수 파라미터를 그에게 전달해야 한다.여러 수퍼 유형은 콜론 뒤에 있는 쉼표로 구분된 목록에서 지정할 수 있습니다.
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)
}

익명 대상은 로컬과 개인 역할 영역에서만 설명하는 형식으로 사용할 수 있음을 주의하십시오.만약 익명의 대상을 공유 함수의 반환 형식으로 사용하거나 공유 속성의 형식으로 사용한다면, 이 함수나 속성의 실제 형식은 익명의 대상이 성명하는 초형식이고, 어떤 초형식도 성명하지 않으면 Any가 됩니다.익명 대상에 추가된 구성원은 접근할 수 없습니다.
class C {
    //     ,              
    private fun foo() = object {
        val x: String = "x"
    }

    //     ,         Any
    fun publicFoo() = object {
        val x: String = "x"
    }

    fun bar() {
        val x1 = foo().x        //    
        val x2 = publicFoo().x  //   :       “x”
    }
}

대상 표현식의 코드는 그 역할 영역을 포함하는 변수에 접근할 수 있습니다.
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(Scala 다음)은 단일 예제 선언을 쉽게 만듭니다.
object DataProviderManager {
    fun registerDataProvider(provider: DataProvider) {
        // ……
    }

    val allDataProviders: Collection
        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

자신이 사용하는 클래스의 이름(다른 이름의 한정자가 아님)은 클래스의 반생 대상(명명 여부에 관계없이)에 대한 인용을 사용할 수 있습니다.
class MyClass1 {
    companion object Named { }
}

val x = MyClass1

class MyClass2 {
    companion object { }
}

val y = MyClass2

동반자 객체의 멤버가 다른 언어의 정적 멤버처럼 보일지라도 런타임 시 실제 객체의 인스턴스 멤버로 남습니다. 예를 들어 인터페이스를 구현할 수도 있습니다.
interface Factory {
    fun create(): T
}

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

val f: Factory = MyClass

좋은 웹페이지 즐겨찾기