Kotlin 데이터 클래스

이 튜토리얼에서는 Kotlin 데이터 클래스를 살펴볼 것입니다. Kotlin 클래스 포스트를 읽지 않았다면 진행하기 전에 읽기를 권장합니다.

Kotlin 데이터 클래스

Java에서 POJO 데이터 클래스를 위해 수천 줄의 코드를 작성하는 데 지칩니까? 모든 Java 프로그래머는 어느 정도 단계에서 데이터를 저장하기만 하려는 클래스에 대해 작성해야 하는 코드 라인 수를 메모했을 것입니다. 다음은 Book.java POJO 클래스의 모습입니다:

public class Book {

    private String name;
    private String authorName;
    private long lastModifiedTimeStamp;
    private float rating;
    private int downloads;


    public Book(String name, String authorName, long lastModified, float rating, int downloads) {
        this.name = name;
        this.authorName = authorName;
        this.lastModifiedTimeStamp = lastModified;
        this.rating = rating;
        this.downloads = downloads;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAuthorName() {
        return authorName;
    }

    public void setAuthorName(String authorName) {
        this.authorName = authorName;
    }

    public long getLastModifiedTimeStamp() {
        return lastModifiedTimeStamp;
    }

    public void setLastModifiedTimeStamp(long lastModifiedTimeStamp) {
        this.lastModifiedTimeStamp = lastModifiedTimeStamp;
    }

    public float getRating() {
        return rating;
    }

    public void setRating(float rating) {
        this.rating = rating;
    }

    public int getDownloads() {
        return downloads;
    }

    public void setDownloads(int downloads) {
        this.downloads = downloads;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Book that = (Book) o;

        if (downloads != that.downloads)
            return false;
        if (name != null ? !name.equals(that.name) :
                that.name != null) {
            return false;
        }
        return authorName != null ?
                authorName.equals(that.authorName) :
                that.authorName == null;

    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + (authorName != null ?
                authorName.hashCode() : 0);
        result = 31 * result + downloads;
        return result;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", author='" + authorName + '\'' +
                ", lastModifiedTimestamp='" + lastModifiedTimeStamp + '\'' +
                ", rating='" + rating + '\'' +
                ", downloads=" + downloads +
                '}';
    }
}

와우! 단순히 객체에 5개의 필드를 저장하기 위해 96줄의 코드가 있습니다. 여기서는 게터 세터, toString(), equals(), hashCode() 메서드만 있습니다. 우리의 실천에서는 깔끔한 아키텍처와 코드 분리 관행을 따르므로 모든 프로젝트에서 데이터를 저장해야 합니다. 이로 인해 보일러 플레이트 코드가 증가할 수 있습니다. 여기서 Kotlin이 나와서 보일러 플레이트 코드를 줄이는 방법을 제시합니다. 데이터 클래스는 Kotlin에서 보일러 플레이트 코드를 줄이는 대답입니다. 위의 POJO 클래스는 다음과 같이 Kotlin으로 작성할 수 있습니다:

data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)

그것뿐입니다. Kotlin은 96줄의 Java 코드를 한 줄의 코드로 변환합니다. 이것이 Kotlin이 프로젝트에서 보일러 플레이트 코드를 줄이는 방법입니다!

코틀린 데이터 클래스 만들기

다음은 코틀린 데이터 클래스를 만들기 위한 요구 사항입니다.

  • 클래스를 data 키워드로 추가해야 합니다.
  • 주 생성자는 적어도 하나의 매개변수를 가져야 합니다.
  • 주 생성자의 각 매개변수는 val 또는 var로 할당되어야 합니다. 이는 일반 클래스와는 다르며, 여기서 val 또는 var를 지정하는 것이 필수적이지 않습니다.
  • 데이터 클래스에는 abstract, open, sealed, inner을 추가할 수 없습니다.

코틀린 데이터 클래스 내장 메서드

코틀린 데이터 클래스는 다음 함수들을 자동으로 생성합니다.

  • equals()hashCode()
  • toString()은 다음 형식으로 생성됩니다. "Book(name=JournalDev, authorName=Anupam)"
  • 지정된 순서대로 각 매개변수에 대한 componentN() 함수가 생성됩니다. 이를 구조 분해 선언이라고 합니다.
  • copy()

코틀린 데이터 클래스 기능

다음은 데이터 클래스가 제공하는 일부 기능입니다.

  • 기본 생성자에 매개변수가 없는 생성자를 만들려면 기본 생성자에 있는 각 매개변수에 기본값을 지정하십시오.

  • 데이터 클래스는 하위 클래스화를 허용합니다(키워드 open을 언급할 필요가 없음).

  • equals() hashCode()toString() 함수에 대한 명시적 구현을 제공할 수 있습니다.

  • copy()componentN() 함수에 대한 명시적 구현은 허용되지 않습니다.

  • 생성자에서 가시성 수정자를 지정하여 게터와 세터의 가시성을 제어할 수 있습니다.

    data class Book(var name: String,private var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)
    
  • val 매개변수는 암시적으로 세터가 정의되지 않으며(명시적으로도 할 수 없습니다!),

Data Class에서의 기본 및 명명된 매개변수

다음은 우리의 데이터 클래스입니다:

data class Book(var name: String, var authorName: String, var lastModified: Long, var rating: Float, var downloads: Int)

매개변수 중 어느 것에도 기본값이 설정되어 있지 않습니다. 따라서 아래와 같이 각각의 인스턴스화에 대한 인수를 설정해야 합니다.

fun main(args: Array<String>) {
val book = Book("Android Tutorials","Anupam", 1234567, 4.5f, 1000)
}

몇 가지 기본 인수를 설정하고 인스턴스화가 어떻게 변경되는지 확인해 보겠습니다.


data class Book(var name: String, var authorName: String = "Anupam", var lastModified: Long = 1234567, var rating: Float = 5f, var downloads: Int = 1000)
fun main(args: Array<String>) {
var book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)

    book = Book("Kotlin")
    book = Book("Swift",downloads = 500)
    book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
    book = Book("Python","Shubham",rating = 5f)

}

각 인수를 설정하는 대신 명명된 인수를 사용하여 기본이 아닌 인수 및 설정하려는 인수만 설정할 수 있습니다. 명명된 인수를 사용하면 매개변수 이름을 명시적으로 지정한 다음 =를 사용하여 5번째 인수를 두 번째로 설정할 수 있습니다. 이렇게 하면 쉽게 처리할 수 있습니다!

Kotlin Data Class toString() 메서드

toString()은 암시적으로 생성되며 인스턴스의 인수 이름과 레이블을 아래에 표시된 대로 출력합니다.

data class Book(var name: String, var authorName: String = "Anupam", var lastModified: Long = 1234567, var rating: Float = 5f, var downloads: Int = 1000)


fun main(args: Array) {

    var book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    println(book)
    book = Book("Kotlin")
    println(book)
    book = Book("Swift",downloads = 500)
    println(book)
    book = Book("Java","Pankaj",rating = 5f, downloads = 1000)
    println(book.toString())
    book = Book("Python","Shubham",rating = 5f)
    println(book.toString())


}

//다음은 콘솔에 출력됩니다.
//Book(name=Android tutorials, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)
//Book(name=Kotlin, authorName=Anupam, lastModified=1234567, rating=5.0, downloads=1000)
//Book(name=Swift, authorName=Anupam, lastModified=1234567, rating=5.0, downloads=500)
//Book(name=Java, authorName=Pankaj, lastModified=1234567, rating=5.0, downloads=1000)
//Book(name=Python, authorName=Shubham, lastModified=1234567, rating=5.0, downloads=1000)

참고: print 함수는 암묵적으로 toString()을 추가합니다.

Kotlin 데이터 클래스 copy() 메소드

복사 함수는 데이터 클래스의 인스턴스를 복사하여 일부 속성을 수정하는 데 사용됩니다. 데이터 클래스 생성자에서 val 매개변수를 사용하여 인스턴스의 불변 속성을 사용하는 것이 좋습니다. 불변 객체는 다중 스레드 응용 프로그램에서 작업할 때 더 쉽습니다. 따라서 불변 객체의 일부 속성을 변경하여 복사본을 만들려면 copy() 함수를 사용하는 것이 편리합니다.

data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    println(book)

    val newBook = book.copy(name = "Kotlin")
    println(newBook)
}
//다음은 콘솔에 출력됩니다.
//Book(name=Android tutorials, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)
//Book(name=Kotlin, authorName=Anupam, lastModified=1234567, rating=4.5, downloads=1000)

Kotlin Data Class equals()와 hashCode()

hashCode() 메서드는 객체에 대한 해시 코드를 반환합니다. 두 개의 객체가 동일하면 hashCode()는 동일한 정수 결과를 생성합니다. 따라서 equals()hashCode()가 동일한 경우 true를 반환하고 그렇지 않으면 false를 반환합니다.

data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    println("Hashcode is ${book.hashCode()}")

    val newBook = book.copy(name = "Kotlin")
    println("Hashcode is ${newBook.hashCode()}")

    val copyBook = book.copy()
    println("Hashcode is ${copyBook.hashCode()}")


    if(copyBook.equals(book))
        println("copyBook and book are equal")

    if(!book.equals(newBook))
        println("newBook and book are NOT equal")

}

//다음은 콘솔에 출력됩니다.
//해시코드는 649213087입니다
//해시코드는 1237165820입니다
//해시코드는 649213087입니다
//copyBook 및 book은 동일합니다
//newBook 및 book은 동일하지 않습니다

첫 번째와 세 번째 객체의 해시 코드가 동일하므로 이들은 동일합니다. 참고: equals() 메서드는 코틀린에서 ==과 동등합니다.

Destructuring Declarations

componentN() 함수를 사용하면 생성자에서 지정한 매개변수의 순서대로 각 인수에 액세스할 수 있습니다. N은 생성자의 매개변수 수입니다.

data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array<String>) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)

    println(book.component1()) //Android tutorials
    println(book.component2()) //Anupam
    println(book.component3()) //1234567
    println(book.component4()) //4.5
    println(book.component5()) //1000
    
}

파괴 선언을 사용하면 아래에 표시된대로 클래스 객체에서 속성으로 인수에 액세스할 수 있습니다.

data class Book(val name: String, val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array<String>) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    val (n,a,date,rating,downloads) = book
}

참고: 위의 함수에서 private와 같은 가시성 수정자가 인수 중 하나에 설정되어 있으면 해당 인수에 액세스할 수 없습니다.

data class Book(val name: String,private val authorName: String = "Anupam", val lastModified: Long = 1234567, val rating: Float = 5f, val downloads: Int = 1000)

fun main(args: Array<String>) {

    val book = Book("Android tutorials","Anupam", 1234567, 4.5f, 1000)
    val (n,a,date,rating,downloads) = book //This won't compile since authorName is private
}

이것으로 코틀린 데이터 클래스에 대한 빠른 요약이 끝났습니다. 참고 자료: Kotlin 문서

Source:
https://www.digitalocean.com/community/tutorials/kotlin-data-class