Класи
Що ж нам робити, якщо ми маємо декілька різних варіацій одного за сенсом об'єкта? Наприклад, ми маємо більше одного кота. То що ж нам робити? Об'єкт тут вже не варіант. На допомогу нам приходить, один з видів об'єкта — Клас. Клас може створюватися в кількох екземплярах, які будуть незалежними один від одного.
На відмінно від object
, як ви вже зрозуміли, class
може мати більше одного екземпляра своєї структури.
Перепишім наш object
на class
:
class Cat {
val name: String = "Мася"
val age: Int = 4
fun meow(): String {
return "meow<3"
}
}
Змінивши ключове слово object
на class
ми вже отримаємо бажаний результат.
Як отримати дані з класу? Для початку, нам потрібно його створити:
fun main() {
/**
* Об'єкти створюються альтернативно виклику функцій.
* Ми створюємо незалежний від інших екземплярів екземпляр та зберігаємо
* його в змінну, як ми це робили з другими типами даних.
*/
val cat = Cat()
println(cat.name)
}
Але, як і раньше, наша структура, має тільки одну варіацію. Можна звісно зробити замість значень змінні й після створення їх змінювати, але класи мають інших підхід.
Конструктор
Насправді в нашому попередньому прикладі, створюючи Cat, ми використовували конструктор. Що таке конструктор?
Якщо ви знаєте англійську, ви швидше за все, зрозуміли, що конструктор (англ. constructor) щось конструює (збирає, створює та інші варіанти перекладу). Використовується для того ж, для чого й аргументи у функцій (насправді, конструктор - це така ж функція, тільки трохи покращена для своїх задач) — для передачі якоїсь необхідної інформації нашому коду (структурі) (наприклад, структура спочатку не знає, як звати нашого кота, ми повинні задати це через конструктор).
Кожен виклик конструктора створює новий екземпляр структури нашого об'єкта, який не залежить від інших.
Як зробити конструктор? За аналогією функцій:
class Cat(name: String, age: Int) {
val name: String = name // параметри класу видні лише в тілі класу
val age: Int = age
fun meow(): String {
return "meow<3"
}
}
Параметри класу видні лише в тілі класу, тобто, поза класом, чи у функції того ж классу ці параметри вже видні не будуть:
class Cat(name: String, age: Int) {
fun meow(): String {
return "$name: meow<3" // Unresolved reference: name
}
}
fun main() {
val cat = Cat("Мася", 4)
println(cat.name) // Unresolved reference: name
}
Після чого, при створенні, ми можемо вказати ці дані:
fun main() {
val cat: Cat = Cat("Мася", 4)
println(cat.name)
}
Таким чином ми можемо передавати дані нашій структурі.
До речі, цей код можна спростити. Котлін дозволяє вказувати властивості (змінні та значення) відразу в конструкторі:
class Cat(val name: String, val age: Int) {
fun meow(): String {
return "meow<3"
}
}
Але все компілюється зрешті в попередній варіант, але, звісно, так простіше.
Об'єкт з попередньої теми можна сприймати як клас, але тільки з одним можливим екземпляром своєї структури. Тому для того, щоб отримати звідти дані, нам не потрібно викликати конструктор.