본문 바로가기
Kotlin

[Kotlin] Data Classes

by 신입같은 3년차 2019. 6. 19.

Data Class


데이터는 보유하지만 아무것도 제공하고 싶지 않을 경우 사용하는 클래스  사용법은 다음과 같다.

data class className ( parameter : type ..) 

 

Data Class는 기본 생성자에서 선언된 속성을 통해 , equals() , hashCode() , copy() , toString() , componentN()등을 생성해 준다 . 

다만 명시적으로 선언하는경우에는 자동으로 생성해주지 않는다 . 

 

Data class를 생성하면서 의미있는 Data Class의 조건은 

- 기본 생성자에 1개이상의 파라미터가 필요하고

- 기본 생성자의 파라미터가 var or val로 선언되어야 한다 . 

- Data 클래스는 abstract , open , sealed , inner가 안된다고 한다 . ( 1.1이후의 버전에서는 sealed class 상속 가능 , interface 구현 가능. )

 

 

Data Class Source Code 


Data클래스 뿐만 아니라 다른 클래스 생성자에서도 기본 값을 설정해 줄 수 있다 . 

 

data class Person (var name : String = "Anonymous", var age : Int = 27 
                    , var gender : String = "남자" )

위와같이 생성하고 파라미터에 아무것도 넣어주지 않을경우 나오는 출력결과를 확인해 보겠습니다 . 

 

매개변수에 값이 할당되지 않는다면 Error가 발생하겠지만 저희는 data class에 default값을 선언해주었기 때문에 매개변수로 값이 넘어오지 않는다면 default값을 대입하게 되었습니다 . 

 

data class Person (var name : String = "Anonymous", var age : Int = 0 , var gender : String = "사람" )

fun main(args: Array<String>) {

    val person1 = Person()
    val person2 = Person(name = "YunJin Choi")
    val person3 = Person(name = "YunJin Choi" , age = 27)
    val person4 = Person(name = "YunJin Choi" , age = 27 , gender = "남자")
    
    println(person1)
    println(person2)
    println(person3)
    println(person4)
    
    /*
    * Person(name=Anonymous, age=0, gender=사람)
    * Person(name=YunJin Choi, age=0, gender=사람)
    * Person(name=YunJin Choi, age=27, gender=사람)
    * Person(name=YunJin Choi, age=27, gender=남자)
    * */
}

 

그런데  뭔가 특이한점이 있습니다 . 객체를 println()을 통하여 호출하였는데 주소값이 나오지 않고 property값들이 나온것을 확인 할수 있습니다 .

 

위에있는 내용을보면 Data클래스는 toString()을 생성해 준다고 적었는데 이것이 바로 toString을 선언해 준 값입니다.

즉 , Data클래스는 property 순서대로 값을 반환해주는 toString()을 생성해 주는것을 알 수 있습니다 .

 

 

Data Class의 copy()


data class 에서는 copy() 메서드를 지원 합니다 .

어디에 쓰는것일까요??

copy()는 객체의 기존값들은 유지하고 특정 매개변수의 값만 고쳐서 새로운 객체를 만들고 싶은경우 사용합니다 . 

바로 소스코드를 통해 확인해 보도록 하겠습니다 . 

data class Person (var name : String = "Anonymous", var age : Int = 0 , var gender : String = "사람" )

fun main(args: Array<String>) {

    val person = Person(name = "YunJin Choi" , age = 27)
    println(person) // Person(name=YunJin Choi, age=27, gender=사람)

    val personCopy = person.copy(gender = "남자")
    println(personCopy) // Person(name=YunJin Choi, age=27, gender=남자)

}

line 6 을 보면 Person객체를 생성할떄 gender를 주지 않아 "사람" 이라는 값이 기본 값으로 담겨있습니다 . 

line 9 에서 copy를 사용하였는데 , 매개변수로 gender밖에 주지 않았지만 출력결과에는 name 과 age가 똑같이 설정 된것을 확인할 수 있습니다 . copy는 위와 같이 특정 값만 고쳐서 새로운 객체르 를만들고 싶은 경우 !! 사용합니다 . 

 

 

Data Class 의 Destructuring Declarations


ES6 JavaScript의 비 구조화 할당이랑 비슷하다고 볼수있습니다 . ( 모르시면 지나가시면 됩니다 .. )

 

기존의 소스코드를 보면 객체에서 해당 값을 사용하기위해 변수에 담을때는 다음과 같이 사용하였습니다 . 

 

data class Person (var name : String = "Anonymous", var age : Int = 0 , var gender : String = "사람" )
fun main(args: Array<String>) {

    val person = Person(age = 27 , gender = "남자" , name = "YunJin Choi")

    val 이름 = person.name
    val 나이 = person.age
    val 성별 = person.gender

    println("${이름} :: ${나이} :: ${성별}")
}

 

바로 다음과 같이 person객체에서 각각으 요소들으 꺼내서 사용하였습니다. 한번만써도 될듯한 person.xx 로 호출을하니 코드가 살짝 길어졌습니다 . 그럼 이제 Destructuring Declarations를 사용해보겠습니다 . 

 

data class Person (var name : String = "Anonymous", var age : Int = 0 , var gender : String = "사람" )

fun main(args: Array<String>) {

    val person = Person(age = 27 , gender = "남자" , name = "YunJin Choi")

    val (이름 , 나이 , 성별  ) = person;

    println("${이름} :: ${나이} :: ${성별}")
}

 person객체만 넣어주었지만 이름 , 나이 , 성별을 담아서 변수로 사용하는것을 확인할 수 있습니다 . 

 

어떻게 이렇게 사용할 수 있을까요?? 바로 data class에서는 componentN()을 생성하여 제공한다는것을 말씀드렸습니다 . 

 

다음 소스코드를 decompile해서 확인하면 

 

componsnt1 , componsnt2, componsnt3 3개의 component()를 통해 name ,age , gender 를 return 순서대로 return 받아 사용할 수 있습니다 . 

반응형

'Kotlin' 카테고리의 다른 글

[Kotlin] permitted by network security policy  (0) 2019.06.27
[Kotlin] Kotlin + Retrofit 통신  (0) 2019.06.26
[Kotlin] 상속  (0) 2019.06.19
[Kotlin] class 의 활용 및 개념  (0) 2019.06.19
[Kotlin] Package , Return and Jumps  (0) 2019.06.19

댓글