본문 바로가기

Kotlin

Kotlin - 데이터 클래스(Data class)

https://kotlinlang.org/docs/data-classes.html

 

Data classes | Kotlin

 

kotlinlang.org

 

코틀린에서 데이터 클래스는 데이터를 담는 용도에 주로 사용되고, data 키워드를 이용해 선언한다.

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

컴파일러는 주 생성자에 포함된 속성값을 대상으로 아래 함수들을 자동으로 생성한다.

  • .equals() / .hashCode()
  • .toString()
  • .componentN()
  • .copy()
fun derivedMembers() {
    val u1 = User("John", 25)
    val u2 = User("John", 25)
    val u3 = User("John", 26)

    println("equals: ${u1.equals(u2)}") // equals: true
    println("equals: ${u1.equals(u3)}") // equals: false

    println("hashCode: ${u1.hashCode()}") // hashCode: 71750734

    println("toString: ${u1.toString()}") // toString: User(name=John, age=25)

    println("component1: ${u1.component1()}") // component1: John
    println("component2: ${u1.component2()}") // component2: 25

    val u4 = u3.copy()
    println("copy: ${u4.toString()}") // copy: User(name=John, age=26)
}

데이터 클래스는 아래 조건을 충족 시켜야 한다.

  • 주 생성자에 최소 한개 이상의 파라미터가 존재 해야 한다.
  • 주 생성자의 파라미터는 val 또는 var 키워드로 선언 되어야 한다.
  • 데이터 클래스는 abstract, open, sealed, inner 클래스 일 수 없다.

데이터 클래스에서 자동으로 생성되는 멤버들 (.toString(), .equals()...)은 아래 규칙을 따른다.

  • 명시적으로 멤버(.equals(), .hashCode()...)를 구현하거나, 부모 클래스에 final 로 구현되어 있다면 해당 멤버는 생성되지 않는다.
  • 상위 클래스에 .componentN() 함수가 "open" 으로 정의되어 있다면 자식 데이터 클래스에서는 해당 함수를 재 정의한다. .componentN() 함수가 재정의 불가능한 형태로 정의 되어 있다면 에러가 발생한다.
  • .componentN() 과 .copy() 함수를 명시적으로 구현하는 것은 허용되지 않는다.

 

클래스 본문에 선언된 속성 (Properties declared in the class body)

컴파일러는 기본적으로 주 생성자(primary constructor) 에 정의된 속성값으로만 함수들을 생성한다. 이 함수들에서 특정 속성값을 제외 하고 싶다면 주 생성자가 아닌 클래스 본문에 속성을 선언 하면 된다.

data class Person(val name: String) {
	var age: Int = 0
}


fun propertiesDeclaredInClass() {
    val p1 = PersonDataClass("John")
    p1.age = 25

    val p2 = PersonDataClass("John")
    p2.age = 27

    println("equals: ${p1.equals(p2)}") // equals: true
    println("toString: ${p1.toString()}") // toString: PersonDataClass(name=John)
}

 

Copying

.copy() 함수는 오브젝트의 일부 값을 복사한 새로운 오브젝트를 생성할때 사용한다.

fun copying() {
    val u1 = User("John", 25)
    val u2 = u1.copy()
    println("copy: ${u2.toString()}") // copy: User(name=John, age=25)

//    일부 값을 변경해서 복사할 수 있다.
    val u3 = u1.copy(age = 30)
    println("copy: ${u3.toString()}") // copy: User(name=John, age=30)
}

 

Data classes and destructuring declarations

아래 예제와 같은 식으로 destructuring 이 가능하다.

fun desctructuring() {
    val u1 = User("John", 25)
    val (name, age) = u1
    println("name: $name, age: $age") // name: John, age: 25
}

 

Standard data classes

표준 라이브러리중에 Pair, Triple 클래스가 있지만, 대부분의 경우 속성에 이름을 지정할 수 있는 데이터 클래스를 사용하는 것이 좋다.

반응형