Data class kotlin component

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

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

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

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

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

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

  • Основной конструктор должен иметь как минимум один параметр;
  • Все параметры основного конструктора должны быть отмечены, как val или var ;
  • Классы данных не могут быть абстрактными, open, sealed или inner;

Дополнительно, генерация членов классов данных при наследовании подчиняется следующим правилам:

  • Если существуют явные реализации equals() , hashCode() или toString() в теле класса данных или final реализации в суперклассе, то эти функции не генерируются, а используются существующие реализации;
  • Если суперкласс включает функции componentN() , которые являются открытыми и возвращают совместимые типы, соответствующие компонентные функции создаются для класса данных и переопределяют функции суперкласса. Если функции суперкласса не могут быть переопределены из-за несовместимости сигнатур или потому что они final , выдаётся сообщение об ошибке;
  • Предоставление явных реализаций для функций componentN() и copy() не допускается.

Классы данных могут расширять другие классы (см. примеры в статье Изолированные классы).

On the JVM, if the generated class needs to have a parameterless constructor, default values for the properties have > to be specified (see [Constructors](classes.md#constructors)). —>

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

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

Свойства, объявленные в теле класса

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

data class Person(val name: String)

Только свойство name будет учитываться в реализациях функций toString() , equals() , hashCode() и copy() , и будет создана только одна компонентная функция component1() . Даже если два объекта класса Person будут иметь разные значения свойств age , они будут считаться равными.

val person1 = Person("John") val person2 = Person("John") person1.age = 10 person2.age = 20 

Копирование

Используйте функцию 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 . Однако, в большинстве случаев, именованные классы данных являются лучшим решением, потому что делают код более читаемым, избегая малосодержательные имена для свойств.

Читайте также:  Массивы и словари питон

© 2015—2023 Open Source Community

Источник

Data class: класс данных в Kotlin

Data class — это простой класс в Kotlin, который используется для хранения данных или состояния и содержит стандартную функциональность. Ключевое слово data используется для объявления класса как класса данных.

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

Объявление класса данных должно содержать по крайней мере один первичный конструктор с аргументом свойства(val или var).

Класс данных внутри содержит следующие функции:

  • equals(): Boolean
  • hashCode(): Int
  • toString(): String
  • component(): функции, соответствующие свойствам
  • copy()

Благодаря наличию вышеперечисленных функций внутри класса данных Data class исключает шаблонный код.

Компрессия между классом данных Java и классом данных Kotlin

Если мы хотим создать запись пользователя в Java с использованием класса данных, потребуется много шаблонного кода.

import java.util.Objects; public class User < private String name; private int id; private String email; public User(String name, int id, String email) < this.name = name; this.id = id; this.email = email; >public String getName() < return name; >public void setName(String name) < this.name = name; >public intgetId() < return id; >public void setId(int id) < this.id = id; >public String getEmail() < return email; >public void setEmail(String email) < this.email = email; >@Override public boolean equals(Object o) < if(this == o) return true; if(!(o instanceof User)) return false; User user =(User) o; return getId() == user.getId() && Objects.equals(getName(), user.getName()) && Objects.equals(getEmail(), user.getEmail()); >@Override public inthashCode() < return Objects.hash(getName(), getId(), getEmail()); >@Override public String toString() < return "User'; > >

Вызов конструктора вышеуказанного класса данных Java с использованием объекта класса User как

Приведенный выше код класса данных Java переписан в коде данных Kotlin в одну строку:

data class User(var name: String, var id: Int, var email: String)

Вызов конструктора вышеуказанного класса данных Kotlin с использованием объекта класса User:

User(name=Ashu, [email protected])

Требования к классу данных

Чтобы создать класс данных, нам необходимо выполнить следующие требования:

  • Класс содержит первичный конструктор по крайней мере с одним параметром.
  • Параметры основного конструктора, помеченные как val или var.
  • Класс данных не может быть абстрактным, внутренним, открытым или запечатанным.
  • До версии 1.1 класс данных может реализовывать только интерфейс. После этого классы данных могут расширять другие классы.
Читайте также:  Java check is array is empty

Методы класса данных Kotlin toString()

Класс данных Kotlin фокусируется только на данных, а не на реализации кода.

Давайте посмотрим на простую программу без класса данных. В этом классе мы пытаемся напечатать ссылку на класс Product, используя его объект.

class Product(varitem: String, var price: Int) fun main(agrs: Array)

При печати ссылки на класс Product отображается hashCode() с именем класса Product. Не печатает данные.

Вышеупомянутая программа переписана с использованием класса данных и печати ссылки на класс продукта и отображения данных объекта. Это происходит потому, что класс данных внутри содержит функцию toString(), которая отображает строковое представление объекта.

data class Product(varitem: String, var price: Int) fun main(agrs: Array)

Product(name=laptop, price=25000)

classequals() и hashCode()

Метод equal() используется для проверки того, что другой объект «равен» текущему объекту. При сравнении двух или более hashCode() метод equals() возвращает true, если hashCode() равны, в противном случае он возвращает false.

Давайте рассмотрим пример, в котором обычный класс сравнивает две ссылки одного и того же класса Product, имеющие одинаковые данные.

class Product(varitem: String, var price: Int) fun main(agrs: Array)

В приведенной выше программе ссылка p1 и ссылка p2 имеют разные ссылки. Из-за разных эталонных значений в p1 и p2 при сравнении отображается ошибка.

Вышеупомянутая программа переписывается с использованием Data-класса, печатая ссылку на класс продукта и отображая данные объекта.

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

data class Product(varitem: String, var price: Int) fun main(agrs: Array)

Метод copy()

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

data class Product(var item: String, var price: Int) fun main(agrs: Array)

p1 object contain data : Product(item=laptop, price=25000) p2 copied object contains default data of p1: Product(item=laptop, price=25000) p3 contain altered data of p1 : Product(item=laptop, price=20000)

Аргументы по умолчанию и именованные аргументы в Data-класс

Мы также можем назначить аргументы по умолчанию в основном конструкторе класса данных. Эти значения по умолчанию могут быть изменены позже в программе, если это необходимо.

data class Product(var item: String = «laptop», var price: Int = 25000) fun main(agrs: Array)

Product(item=laptop, price=20000)

Источник

Data classes

It is not unusual to create classes whose main purpose is to hold data. In such classes, some standard functionality and some utility functions are often mechanically derivable from the data. In Kotlin, these are called data classes and are marked with data :

The compiler automatically derives the following members from all properties declared in the primary constructor:

  • equals() / hashCode() pair
  • toString() of the form «User(name=John, age=42)»
  • componentN() functions corresponding to the properties in their order of declaration.
  • copy() function (see below).
Читайте также:  Php mysqli result row count

To ensure consistency and meaningful behavior of the generated code, data classes have to fulfill the following requirements:

  • The primary constructor needs to have at least one parameter.
  • All primary constructor parameters need to be marked as val or var .
  • Data classes cannot be abstract, open, sealed, or inner.

Additionally, the generation of data class members follows these rules with regard to the members’ inheritance:

  • If there are explicit implementations of equals() , hashCode() , or toString() in the data class body or final implementations in a superclass, then these functions are not generated, and the existing implementations are used.
  • If a supertype has componentN() functions that are open and return compatible types, the corresponding functions are generated for the data class and override those of the supertype. If the functions of the supertype cannot be overridden due to incompatible signatures or due to their being final, an error is reported.
  • Providing explicit implementations for the componentN() and copy() functions is not allowed.

Data classes may extend other classes (see Sealed classes for examples).

On the JVM, if the generated class needs to have a parameterless constructor, default values for the properties have to be specified (see Constructors).

Properties declared in the class body

The compiler only uses the properties defined inside the primary constructor for the automatically generated functions. To exclude a property from the generated implementations, declare it inside the class body:

Only the property name will be used inside the toString() , equals() , hashCode() , and copy() implementations, and there will only be one component function component1() . While two Person objects can have different ages, they will be treated as equal.

Copying

Use the copy() function to copy an object, allowing you to alter some of its properties while keeping the rest unchanged. The implementation of this function for the User class above would be as follows:

You can then write the following:

Data classes and destructuring declarations

Component functions generated for data classes make it possible to use them in destructuring declarations:

val jane = User(«Jane», 35) val (name, age) = jane println(«$name, $age years of age») // prints «Jane, 35 years of age»

Standard data classes

The standard library provides the Pair and Triple classes. In most cases, though, named data classes are a better design choice because they make the code more readable by providing meaningful names for the properties.

Источник

Оцените статью