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 ООП Узагальнені класи і функції


узагальнення


Узагальнені класи і функції

Узагальнення представляють техніку, за допомогою якої методи і класи можуть використовувати об'єкти, типи яких на момент визначення класів і методів невідомі. Узагальнення дозволяють визначати шаблони, в які можна підставляти різні типи.


узагальнені типи

Узагальнені типи (generic types) представляють типи, в яких типи об'єктів параметризованих. Наприклад, щоб унікально ідентифікувати кожен об'єкт певного типу, ми можемо визначити властивість-ідентифікатор, яке буде мати у кожного об'єкта унікальне значення. Однак який тип буде представляти дане властивість? Залежно від умов ми можемо використовувати числові ідентифікатори або строкові або якихось інших типів даних. Щоб не прив'язуватися до конкретного типу на момент визначення класу, ми можемо зробити клас узагальненим:

class Person<T>(val id: T, _name: String){
    var name: String = _name
}}

Клас Person використовує параметр T. Параметри вказуються після імені класу в кутових дужках. Даний параметр буде представляти певний тип даних, який на момент визначення класу невідомий. У первинному конструкторі визначається властивість id, яке представляє ідентифікатор. Воно являє тип, який передається через параметр T. На момент визначення класу Person ми не знаємо, що це буде за тип.

Також первинний конструктор приймає звичайний параметр _name, який має тип String і значення якого передається властивості name.

При використанні типу Person необхідно його типізувати певним типом, тобто вказати, який тип буде передаватися через параметр T:

fun main(args: Array<String>) {
 
    var tom: Person<Int> = Person<Int>(367, "Tom")
    var bob: Person<String> = Person<String>("A65", "Bob")
 
    println("${tom.id} - ${tom.name}")
    println("${bob.id} - ${bob.name}")
}
 
class Person<T>(val id: T, _name: String){
    var name: String = _name
}

Для типізації об'єкта після назви типу в кутових дужках вказується конкретний тип:

var tom: Person<Int>

В даному випадку ми говоримо, що параметр T фактично буде представляти тип Int. Тому в конструктор об'єкта Person для властивості id необхідно передати числове значення Int:

Person<Int>(367, "Tom")

Другий об'єкт Типізуються типом String, тому в конструкторі для властивості id передається рядок:

var bob: Person<String> = Person<String>("A65", "Bob")

Якщо конструктор використовує параметр T, то в принципі ми можемо не вказувати, яким типом Типізуються об'єкт - даний тип буде виводитися з типу параметра конструктора:

var tom = Person(367, "Tom")
var bob = Person("A65", "Bob")

Можна одночасно використовувати кілька параметрів:

fun main(args: Array<String>) {
 
    var word1: Word<String, String> = Word("one", "один")
    var word2: Word<String, Int> = Word("two", 2)
 
    println("${word1.source} - ${word1.target}")    // one - один
    println("${word2.source} - ${word2.target}")    // two - 2
}
 
class Word<K, V>(_source: K, _target: V){
    val source: K = _source
    var target: V = _target
}

узагальнені функції

Функції, як і класи, можуть бути узагальненими.

fun main(args: Array<String>) {
 
    var item1 = getItem<Int>(1,2,3)
    var item2 = getItem<String>("red", "green", "blue")
    println(item1)
    println(item2)
}
val random = java.util.Random()
 
fun <T> getItem(a: T, b: T, c: T): T{
    var n = random.nextInt(3)
    if(n==1) return a
    else if(n==2) return b
    else return  c
}

Функція getItem() параметризованих параметром T. Параметр також вказується в кутових дужках перед назвою функції. Функція приймає три параметри типу T і повертає об'єкт цього ж типу. У ній використовується стандартний клас Random, який визначений в Java і який представляє генератор випадкових чисел. І в залежності від сгенерірованни числа повертається те чи інше значення. І при використанні функції ми можемо передавати в неї дані будь-яких типів.


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