Skip to content

Latest commit

 

History

History
87 lines (66 loc) · 5.93 KB

data-classes.md

File metadata and controls

87 lines (66 loc) · 5.93 KB
type layout category title url
doc
reference
Classes and Objects
Классы данных

Классы данных

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

data class User(val name: String, val age: Int)

Такой класс называется классом данных. Компилятор автоматически извлекает все члены данного класса из свойств, объявленных в первичном конструкторе:

  • пара функций equals()/hashCode(),
  • toString() в форме "User(name=Jhon, age=42)",
  • функции componentN(), которые соответствуют свойствам, в зависимости от их порядка либо объявления,
  • функция copy() (см. ниже)

Если какая-либо из этих функций явно определена в теле класса (или унаследована от родительского класса), то генерироваться она не будет.

Для того, чтобы поведение генерируемого кода соответствовало здравому смыслу, классы данных должны быть оформлены с соблюдением некоторых требований:

  • Первичный конструктор должен иметь как минимум один параметр;
  • Все параметры первичного конструктора должны быть отмечены, как val или var;
  • Классы данных не могут быть абстрактными, open, sealed или inner;
  • Дата-классы не могут наследоваться от других классов (но могут реализовывать интерфейсы).

Начиная с версии 1.1, классы данных могут расширять другие классы (см. примеры в Sealed classes)

Для того, чтобы у сгенерированного в JVM класса был конструктор без параметров, значения всех свойств должны быть заданы по умолчанию (см. Конструкторы)

 data class User(val name: String = "", val age: Int = 0)

Копирование

Довольно часто нам приходится копировать объект с изменением только некоторых его свойств. Для этой задачи генерируется функция 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") // выводит "Jane, 35 years of age"

Стандартные классы данных

Стандартная библиотека предоставляет Pair и Triple. Однако, в большинстве случаев, проименованные классы данных являются лучшим решением, потому что делают код более читаемым, избегая малосодержательные имена для свойств.

Статья на эту тему на Хабре