Классы данных
Не является редкостью создание классов, основное назначение которых — хранение данных. В таких классах часто стандартные функции и утилитарные функции могут быть автоматически выведены из данных. В Kotlin они называются классами данных и помечаются как data.
data class User(val name: String, val age: Int)
Компилятор автоматически выводит следующие члены из всех свойств, объявленных в первичном конструкторе:
equals()/hashCode()паруtoString()в формате"User(name=John, age=42)"componentN()функции, соответствующие свойствам в порядке объявления.Функцию
copy()(см. ниже).
Для обеспечения согласованности и осмысленного поведения сгенерированного кода, классы данных должны удовлетворять следующим требованиям:
Первичный конструктор должен иметь как минимум один параметр.
Все параметры первичного конструктора должны быть помечены как
valилиvar.Классы данных не могут быть абстрактными, открытыми, закрытыми или вложенными.
Кроме того, генерация членов класса данных подчиняется этим правилам в отношении наследования членов:
Если в теле класса данных есть явные реализации
equals(),hashCode(), илиtoString(), илиfinalреализации в суперклассе, то эти функции не генерируются, и используются существующие реализации.Если супертип имеет
componentN()функции, которые являютсяopenи возвращают совместимые типы, соответствующие функции генерируются для класса данных и переопределяют функции супертипа. Если функции супертипа не могут быть переопределены из-за несовместимых сигнатур или из-за того, что они являются final, сообщается об ошибке.Предоставление явных реализаций функций
componentN()иcopy()запрещено.
Классы данных могут расширять другие классы (см. Закрытые классы для примеров).
data class User(val name: String = "", val age: Int = 0)
Свойства, объявленные в теле класса
Компилятор использует только свойства, определенные внутри первичного конструктора, для автоматически сгенерированных функций. Чтобы исключить свойство из сгенерированных реализаций, объявите его внутри тела класса:
data class Person(val name: String) {
var age: Int = 0
}
В этом примере, только свойство name может быть использовано внутри реализаций toString(), equals(), hashCode(), и copy(), и существует только одна функция компонента component1(). Свойство age не может быть использовано внутри реализаций toString(), equals(), hashCode(), и copy(), потому что оно объявлено внутри тела класса. Если два объекта Person имеют разный возраст, но одинаковый name, они считаются равными. Это потому, что функция equals() может проверять только равенство свойства name. Например:
data class Person(val name: String) {
var age: Int = 0
}
fun main() {
//sampleStart
val person1 = Person("John")
val person2 = Person("John")
person1.age = 10
person2.age = 20
println("person1 == person2: ${person1 == person2}")
// person1 == person2: true
println("person1 with age ${person1.age}: ${person1}")
// person1 with age 10: Person(name=John)
println("person2 with age ${person2.age}: ${person2}")
// person2 with age 20: Person(name=John)
//sampleEnd
}
Копирование
Используйте функцию copy() для копирования объекта, позволяя изменить некоторые его свойства, сохраняя при этом остальные неизменными. Реализация этой функции для класса User выше будет следующей:
fun copy(name: String = this.name, age: Int = this.age) = User(name, age)
Затем вы можете написать следующее:
val jack = User(name = "Jack", age = 1) val olderJack = jack.copy(age = 2)
Классы данных и деструктурирующие объявления
Функции компонентов, сгенерированные для классов данных, позволяют использовать их в деструктурирующих объявлениях:
val jane = User("Jane", 35)
val (name, age) = jane
println("$name, $age years of age") // prints "Jane, 35 years of age"
Стандартные классы данных
Стандартная библиотека предоставляет классы Pair и Triple. Однако в большинстве случаев использование именованных классов данных — лучший выбор, так как это делает код более читабельным, предоставляя осмысленные имена для свойств.
© 2010–2023 JetBrains s.r.o. and Kotlin Programming Language contributors
Licensed under the Apache License, Version 2.0.
https://kotlinlang.org/docs/data-classes.html