Kotlin в IntelliJ IDEA Kotlin змінні Kotlin типи даних Kotlin операції з числами Kotlin умовні вирази Kotlin умовні конструкції Kotlin цикли Kotlin послідовності Kotlin масиви Kotlin функціональне програмування Kotlin змінна кількість параметрів. Vararg Kotlin повернення результату. оператор return Kotlin однорядкові і локальні функції Kotlin перевантаження функцій Kotlin Лямбда-вирази Kotlin функції вищого порядку Kotlin Анонімні функції Kotlin ООП Класи і об'єкти Kotlin ООП властивості Kotlin ООП конструктор Kotlin ООП функції в класах Kotlin ООП Пакети та імпорт Kotlin ООП модифікатори видимості Kotlin ООП вкладені класи Kotlin ООП інтерфейси Kotlin ООП спадкування Kotlin ООП Перевизначення методів і властивостей Kotlin ООП Абстрактні класи та методи Kotlin ООП Data-класи Kotlin ООП перерахування enums Kotlin ООП Null і nullable-типи Kotlin ООП Обробка винятків Kotlin ООП перетворення типів Kotlin ООП Інфіксна функція Kotlin ООП функції розширення Kotlin ООП Узагальнені класи і функції Kotlin ООП обмеження узагальнень Kotlin ООП Варіантність, коваріантність і контраваріантність Kotlin Колекції. Змінювані і незмінні колекції Kotlin Колекції. LIST список Kotlin Колекції. Set Kotlin Колекції. Map

Kotlin ООП вкладені класи


У Kotlin класи можуть бути визначені в інших класах. Такі класи (вкладені класи або nested classes) зазвичай виконують якусь допоміжну роль, а визначення їх усередині класу дозволяє розмістити їх якомога ближче до того місця, де вони безпосередньо використовуються.

Наприклад, в наступному випадку визначається вкладений клас:

class Account{
    class Transaction{
 
    }
}

В даному випадку клас Transaction є вкладеним, а клас Account - зовнішнім.

За замовчуванням вкладені класи мають модифікатор видимості public, тобто вони видимі в будь-якій частині програми. Але для звернення до вкладеного класу треба використовувати ім'я зовнішнього класу. Наприклад, створення об'єкта вкладеного класу:

val t = Account.Transaction()

Якщо необхідно обмежити сферу застосування вкладеного класу тільки зовнішнім класом, то слід визначити вкладений клас з модифікатором private:

class Account{
    private class Transaction{
 
    }
}

внутрішні класи

Варто враховувати, що вкладений клас за замовчуванням не має доступу до властивостей і функцій зовнішнього класу. Наприклад, в наступному випадку при спробі звернутися до властивості зовнішнього класу ми отримаємо помилку:

class Account{
    private var sum: Int = 3450
    class Transaction{
        fun pay(s: Int){
            sum -= s        // ! Ошибка
        }
    }
}

Щоб вкладений клас міг мати доступ до властивостей і функцій зовнішнього класу, необхідно визначити вкладений клас з ключовим словом inner . Такий клас ще називають внутрішнім класом (inner class), щоб відрізняти від звичайних вкладених класів. наприклад:

fun main(args: Array<String>) {
 
    Account().Transaction().pay(1200)
}
class Account{
 
    private var sum: Int = 3450
    fun display(){
        println("sum = $sum")
    }
     
    inner class Transaction{
        fun pay(s: Int){
            sum -= s
            display()
        }
    }
}

Тепер клас Transaction визначено з ключовим словом inner, тому має повний доступ до властивостей і функцій зовнішнього класу Account. Але тепер якщо ми хочемо використовувати об'єкт подібного вкладеного класу, то необхідно створити об'єкт зовнішнього класу:

Account().Transaction().pay(1200)

збіг імен

Але що якщо властивості і функції внутрішнього класу називаються також, як і властивості і функції зовнішнього класу? У цьому випадку внутрішній клас може звернутися до властивостей і функцій зовнішнього через конструкцію this@название_класса.имя_свойства_или_функции :

class A{
    private val n: Int = 1
    inner class B{
        private val n: Int = 1
        fun action(){
            println(n)          // n из класса B
            println(this.n)     // n из класса B
            println(this@B.n)   // n из класса B
            println(this@A.n)   // n из класса A
        }
    }
}

Наприклад, перепишемо випадок вище з класами Account і Transaction наступним чином:

fun main(args: Array<String>) {
 
    Account().Transaction(1200).pay()
}
class Account{
    private var sum: Int = 3450
    fun display(){
        println("sum = $sum")
    }
    inner class Transaction(s: Int){
        private var sum : Int = 0
        init {
            this.sum = s
        }
        fun pay(){
            this@Account.sum -= this@Transaction.sum
            display()
        }
    }
}

Наш партнер:
beta test mp3 playlist downloader