[Kotlin] Data Class란
Data class 란
데이터를 보유하는 것이 주된 목적인 클래스입니다.
Ex) User의 data class
data class User(val name: String, val age: Int)
데이터 클래스의 충족 조건
- 주요 생성장에는 적어도 하나의 파라매터가 필요하다.
- 모든 주요 생성자 파라매터는 val 혹은 var로 지정
- 데이터 클래스는 추상 클래스, open 클래스, sealed클래스, inner클래스 일수 없다.
- 1.1버전 이후 데이터 클래스는 다른 클래스를 확장할 수 있다.
클래스에 파라매터가 없는 생성자가 필요한 경우, 모든 프로퍼티의 기본값을 지정할 필요가 있다.
data class User(val name: String = "", val age: Int = 0)
컴파일러에서는 기본생성자에 선언된 모든 속서에서 다음 멤버를 자동으로 파생시킨다.
- equals() / hasCode()
- toString()
- 프로퍼티 선언 순서에 따라 대응하는 componentN() 함수
- copy()
equals() / hasCode()
equals는 User라는 데이터 클래스의 동일여부를 따지는 함수이다.
hashCode는 객체를 식별할 수 있는 값을 반환한다.(주소값은 유니크해서 일반적으로 주소값을 반환하지만, 주소값이 아닐 수 있습니다. 중요한건 해당 값은 "유니크" 해야 한다는 점입니다.)
data class User(val name: String, val age: Int) {
var isSuperStar: Boolean = false
override fun equals(other: Any?): Boolean {
if (other == null || other !is User) return false
return this.name == other.name && this.age == other.age && this.isSuperStar == other.isSuperStar
}
override fun hashCode(): Int {
return Objects.hash(name, age, isSuperStar)
}
}
fun main() {
val user1 = User("minsu", 10)
user1.isSuperStar = true
val user2 = User("minsu", 10)
print(user1 == user2) // false
}
equals 와 hashCode는 같이 재정의 해야한다. 둘 중 하나만 재정의하게 되면 같은 값 객체라도 해시값이 다른 문제가 발생할 수 있기때문이이다.
toString()
toString은 data class 정의에서 매우 편한 기능 중 하나이다.
data에 포함되어 있는 데이터를 빠르게 출력하여 볼 수 있으며, 아래 변수를 추가로 정의한다고 해도 toString을 매번 수정할 필요 없이 kotlin에서 자동으로 정의해 주기 때문에 매우 편하다.
@NotNull
public String toString() {
return "User(name=" + this.name + ", age=" + this.age + ")";
}
componentN
아래와 같이 ()로 묶어주고, 순서대로 변수 이름을 명시하면 편하게 사용이 가능하다.
val (name, age) = User("당신의 이름", 20)
tvName.text = name
tvAge.text = age.toString()
이렇게 정의하면 name, age의 값에 직접 접근이 가능하다. 다만, data class가 거대하다면 componentN은 오히려 불편할 수 있다.
copy()
immutable 정의에서 매우 유용하게 사용할 수 있다.
data class User(
val name: String,
val age: Int,
val id: Long
)
val olduser = User("사용자 이름", 20, 1000)
val newuser = User(olduser.name, olduser.age, 1001)
예를 들어, 위와 같은 값이 주어졌을때, newuser의 id값만 교체하고 싶다면 위 코드와 같이 user의 각각 값을 모두 복사하고, 마지막은 id값은 카피가 아닌 직접 수정해서 정의할 수 있다. 하지만 copy를 활용 하여 더 빠른 수정이 가능한데
val olduser = User("사용자 이름", 20, 1000)
val newuser = olduser.copy(id = 1001)
이와 같이 copy를 이용하여 더 빠르고 쉽게 이용할 수 있다.
참고 문서 :
https://kotlinlang.org/docs/data-classes.html
https://thdev.tech/kotlin/2020/09/15/kotlin_effective_02/