English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Основы Kotlin

Контроль потока в Kotlin

Функции Kotlin

Строки Kotlin

Ориентированный на объекты (OOP) Kotlin

Данные классы (Data) в Kotlin

В этой статье вы узнаете, как создавать данные классы в Kotlin. Вы также узнаете требования, которые должны выполнять данные классы, и их стандартные функции.

Может возникнуть такая ситуация: вам нужно создать класс, предназначенный только для хранения данных. В этом случае вы можете отметить класс как data, чтобы создать данные класс. Например:

data class Person(val name: String, var age: Int)

Для этого класса компилятор автоматически создает:

  • Функция copy(), equals() и hashCode() и форма toString() главного конструктора

  • Функция componentN()

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

Требования к данным классам в Kotlin

Требования такие:

  • Главный конструктор должен иметь至少 один параметр.

  • Параметры главного конструктора должны быть помечены как val (только чтение) или var (чтение и запись).

  • Класс не может быть открытым, абстрактным, внутренним или запечатанным.

  • Этот класс может расширять другие классы или реализовывать интерфейсы. Если вы используете версию Kotlin 1.1 и более ранние, этот класс может реализовывать только интерфейсы.

Пример: Использование данных классов в Kotlin

data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
    val jack = User("jack", 29)
    println("name = ${jack.name}")
    println("age = ${jack.age}")
}

При выполнении этого программы выводится:

name = jack
age = 29

Когда вы декларируете данные класс, компилятор автоматически создает несколько функций на заднем плане, таких как toString(), equals(), hashCode() и т.д., что помогает поддерживать простоту кода. Если вы используете Java, вам нужно написать много шаблонного кода.
Давайте используем следующие функции:

Функция copy() - копирование

Для данных классов можно использовать функцию copy() для создания копии объекта с различными свойствами. Принцип его работы таков:

data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
    val u1 = User("John", 29)
   
    //Использование функции копирования для создания объекта
    val u2 = u1.copy(name = "Randy")
    println("u1: name = ${u1.name}, name = ${u1.age}")
    println("u2: name = ${u2.name}, name = ${u2.age}")
}

При выполнении этого программы выводится:

u1: name = John, name = 29
u2: name = Randy, name = 29

Метод toString() - возвращает строку

Функция toString() возвращает строковое представление объекта.

data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
    val u1 = User("John", 29)
    println(u1.toString())
}

При выполнении этого программы выводится:

User(name=John, age=29)

hashCode() и equals()

Метод hasCode() возвращает хеш-код объекта. Если два объекта равны, то hashCode() будет производить одинаковый целочисленный результат.

Если два объекта равны (hashCode() одинаковы), то equals() возвращает true. Если объекты не равны, equals() возвращает false.

data class User(val name: String, val age: Int)
fun main(args: Array<String>) {
    val u1 = User("John", 29)
    val u2 = u1.copy()
    val u3 = u1.copy(name = "Amanda")
    println("u1 hashCode = ${u1.hashCode()}")
    println("u2 hashCode = ${u2.hashCode()}")
    println("u3 hashCode = ${u3.hashCode()}")
    if (u1.equals(u2) == true)
        println("u1 равен u2.")
    else
        println("u1 не равен u2.")
    if (u1.equals(u3) == true)
        println("u1 равен u3.")
    else
        println("u1 не равен u3.")
}

При выполнении этого программы выводится:

u1 hashCode = 71750738
u2 hashCode = 71750738
u3 hashCode = 771732263
u1 равен u2.
u1 не равен u3.

Деструктивное определение

Вы можете использовать деструктивное определение для разложения объекта на несколько переменных. Например:

data class User(val name: String, val age: Int, val gender: String)
fun main(args: Array<String>) {
    val u1 = User("John", 29, "Мужской")
    val (name, age, gender) = u1
    println("name = $name")
    println("age = $age")
    println("gender = $gender")
}

При выполнении этого программы выводится:

name = John
age = 29
gender = Male

Это возможно, потому что компилятор генерирует функцию component() для всех свойств класса данных. Например:

data class User(val name: String, val age: Int, val gender: String)
fun main(args: Array<String>) {
    val u1 = User("John", 29, "Мужской")
    println(u1.component1())     // John
    println(u1.component2())     // 29  
    println(u1.component3())     // "Мужской"
}

При выполнении этого программы выводится:

John
29
Мужской