Область применения методов анонимного объекта - Котлин - PullRequest
1 голос
/ 24 мая 2019

В Kotlin, если я определяю метод для анонимного объекта, иногда я могу получить к нему доступ, а иногда нет. Похоже, это как-то связано с правилами области видимости, но я не уверен, что.

В приведенном ниже примере кода доступ к example3.field.method() приведет к ошибке компиляции. Интересно, что example2.field.method() компилируется просто отлично.

Что может быть объяснением для поведения ниже?

class Example3 {
    val field = object {
        fun method() {}
    }
}

fun showcase() {
    val example1 = object {
        fun method() {}
    }
    example1.method()
    println(example1::class.qualifiedName)

    class Example2 {
        val field = object {
            fun method() {}
        }
    }

    val example2 = Example2()
    example2.field.method()
    println(example2::class.qualifiedName)

    val example3 = Example3()
    // example3.field.method()  // won't compile
    println(example3::class.qualifiedName)
}

Ответы [ 2 ]

5 голосов
/ 24 мая 2019

Из документов Выражения и объявления объектов :

Обратите внимание, что анонимные объекты могут использоваться как типы только в локальных и частные объявления. Если вы используете анонимный объект в качестве типа возврата публичной функции или типа публичной собственности, фактический тип этой функции или свойства будет объявлен супертип анонимный объект или Any, если вы не объявили ни одного супертипа. Пользователи добавленный в анонимный объект не будет доступен.

Показано в примере кода ниже:

class Example4{
    val publicObj = object{
        val x = 1
    }

    private val privateObj = object{
        val x = 2
    }

    fun showcase(){
        val scopedObj = object{
            val x = 3
        }
        println(publicObj.x)    // ERROR : unresolved reference: x
        println(privateObj.x)   // OK
        println(scopedObj.x)    // OK
    }
}
2 голосов
/ 24 мая 2019

Павел дал правильный ответ на ваш вопрос, указав на документацию:

фактическим типом этой функции или свойства будет объявленный супертип анонимного объекта или Any, если вы не объявили ни одного супертипа.

Но просто добавьте, что если вам действительно нужен доступ к example3.field.method(), вы можете объявить супертип для field в Example3:

interface MyInterface {
    fun method()
}

class Example3 {
    val field = object: MyInterface { 
        override fun method() {} 
    }
}

fun main() {
    val example3 = Example3()
    example3.field.method()
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...