References: Do it! 코틀린 프로그래밍

코틀린에서의 데이터 클래스에 대해 알아봅니다.

 

 

1. 데이터 클래스

 

데이터 클래스는 데이터 전달을 위한 클래스라고 말합니다. 

보통 이러한 객체를 DTO(Date Transfer Object)라고 부릅니다.

DTO는 구현 로직을 갖지 않고 순수한 데이터를 표현하기 때문에 보통 속성과 게터/세터를 갖습니다.

 

코틀린에서는 DTO를 위해 데이터 클래스를 정의할 때 게터/세터/toString/equal 등을 직접 구현할 필요 없이 자동으로 구현해 줍니다. 코틀린의 데이터 클래스 내부에선 다음과 같은 메서드를 자동으로 생성해 줍니다.

 

  • 프로퍼티를 위한 게터/세터
  • 비교를 위한 equals()
  • 키 사용을 위한 hashCode()
  • 프로퍼티를 문자열로 변환해 순서대로 보여주는 toString()
  • 객체 복사를 위한 copy()
  • 프로퍼티에 상응하는 component1, component2 등

DTO를 통해 일종의 표준과 같은 약속을 정하면 송신측과 수신 측 모두 데이터를 쉽게 다룰 수 있어 DTO를 사용합니다.

 

 

2. 데이터 클래스 선언 방법

 

데이터 클래스는 data라는 선언자를 이용해서 선언합니다.

데이터 클래스는 다음과 같은 조건을 만족해야 합니다.

  • 주 생성자는 하나 이상의 매개변수를 가져야 합니다.
  • 주 생성자의 모든 매개변수는 var 혹은 val로 지정된 프로퍼티여야 한다.
  • 데이터 클래스는 abstract, open, sealed, inner 키워드를 사용할 수 없다.

단, 필요하다면 부 생성자나 init을 사용해 간단한 로직을 포함할 수 있습니다.

 

다음 예시를 통해 DTO에 대해 알아보겠습니다.

 

data class Customer(var name: String, var email: String){
    var job: String = "Unknown"
    constructor(name: String, email: String, _job: String): this(name, email){ job = _job }
    init { /** Simple logic here. */ }
}
fun main() {
    val cus1 = Customer("smoh", "smoh@mail.com")
    val cus2 = Customer("smoh", "smoh@mail.com")
    println(cus1 == cus2)
    println(cus1.equals(cus2))
    println("${cus1.hashCode()}, ${cus2.hashCode()}")
    println(cus1.toString())
}

 

  • var name: Stirng, var email: String: 주 생성자를 통해 두 프로퍼티를 갖습니다.
  • constructor: 부 생성자를 통해 job 프로퍼티를 하나 더 갖습니다.
  • init: init에 간단한 로직을 포함하게 할 수 있습니다.
  • 이 외에도 코틀린은 자동으로 여러 메서드를 생성해 둡니다.

위의 코드를 수행하면 다음과 같은 결과를 확인할 수 있습니다.

위 처럼 우리가 직접 정의하지 않은 여러 메서드를 코틀린에서 자동으로 추가해주며 바로 사용할 수 있습니다

 

 

 

3. 객체 디스트럭처링.

 

디스트럭처링(Destructuring)은 객체가 갖고 있는 프로퍼티를 개별 변수로 분해하여 할당하는 것을 말합니다.

js의...(Spread syntax)의 구조 분해 할당과 같은 개념으로 보입니다.

 

다음 예시를 통해 디스트럭처링에 대해 알아보겠습니다.

 

data class Customer(var name: String, var email: String){
var job: String = "Unknown"
constructor(name: String, email: String, _job: String): this(name, email){ job = _job }
init { /** Simple logic here. */ }
}
fun myFunc(): Customer { return Customer("smoh92", "smoh92@mail.com") }
fun main() {
    val cus1 = Customer("smoh1", "smoh1@mail.com")
    val (name, email) = cus1
    println("name = $name, email = $email")

    val (_, email2) = cus1

    val name3 = cus1.component1()
    val email3 = cus1.component2()
    println("name = $name3, email = $email3")

    val cus2 = Customer("smoh2", "smoh2@mail.com")
    val customers = listOf(cus1, cus2)
    for((name, email) in customers){ println("name = $name, email = $email") }

    val(myName, myEmail) = myFunc()

    val myLamda = {
        (nameLa, emailLa): Customer ->
        println(nameLa)
        println(emailLa)
    }
    myLamda(cus1)
}

 

  • val (name, email) = cus1: 기본적인 디스트럭처링
  • val (_, email2) = cus1: 디스트럭처링 하지 않을 프로퍼티는 언더바로 표시합니다.
  • val name3 = cus1.component1(): 컴포넌트 순서대로 골라서 디스트럭처링 하는 방법입니다.
  • for((name, email) in customers): 디스트럭처링 해야할 대상이 많은 경우 루프 문을 이용할 수 있습니다.
  • val(myName, myEmail) = myFunc(): 리턴 값이 객체인 함수에 대해서도 디스트럭처링을 적용할 수 있습니다.
  • val myLamda: 람다식을 사용해 디스트럭처링 하는 방법입니다.

해당 예시코드를 수행하면 다음과 같은 결과를 확인할 수 있습니다.

 

 

 

 

 

 

반응형

'Programming' 카테고리의 다른 글

[Kotlin] 34. 봉인 클래스와 열거형 클래스  (0) 2019.09.16
[Kotlin] 33. 내부 클래스  (0) 2019.09.16
[Kotlin] 31. 인터페이스  (0) 2019.09.12
[Kotlin] 30. 추상 클래스  (0) 2019.09.05
[Kotlin] 29. 컴패니언 객체  (0) 2019.09.01

+ Recent posts