이번 영상에서는 코틀린의 Data class에 대해 알아보도록 하겠습니다.
코틀린에서 클래스를 만들 때는 자바의 랭귀지 스펙에 따라서 toString, equals, hashCode라는 메소드를 구현해주어야 합니다. 우선 Person이라는 클래스를 만들고 그 인스턴스를 출력해 보겠습니다. 그러면 Person@랜덤 이라는 값이 출력이 되게 됩니다.
class Person(var name: String, var age: Int, var sex: String)
fun main() {
val person1 = Person("Alice", 20, "Female")
println(person1)
}
// 출력값
Person@37f8bb67
이제 클래스의 toString을 다음과 같이 오버라이드 해주면 랜덤값이 아니라 클래스가 가진 프로퍼티값을 보여주게 됩니다.
class Person(var name: String, var age: Int, var sex: String) {
+ override fun toString(): String {
+ return "Person(name=$name, age=$age, sex=$sex)"
+ }
}
// 출력값
Person(name=Alice, age=20, sex=Female)
equals는 같은 클래스로부터 인스턴스를 만들었을 때, 클래스 내부의 프로퍼티가 일치하면 같은 인스턴스로 취급할지를 판정하는 메소드입니다. 예를 들어 다음과 같은 인스턴스를 만들어 보면, 두 인스턴스는 동일하지 않다는 판정이 나오게 됩니다.
val person2 = Person("Bob", 22, "Male")
val person3 = Person("Bob", 22, "Male")
println(person2 == person3)
// 출력값
false
이제 equals를 다음과 같이 오버라이드 해줍니다. 비교대상이 되는 인스턴스를 받아서 그게 null이거나 Person 클래스가 아닐 경우엔 false를 반환하지만, 인스턴스의 프로퍼티가 일치하게 되면 동일한 객체라는 판정을 받게 됩니다.
class Person(var name: String, var age: Int, var sex: String) {
override fun toString(): String {
return "Person(name=$name, age=$age, sex=$sex)"
}
+ override fun equals(other: Any?): Boolean {
+ if (other == null || other !is Person) return false
+ return name == other.name && age == other.age && sex == other.sex
+ }
}
// 출력값
true
hashCode는 인스턴스의 해시값을 정의하는 메소드입니다. 이 부분을 정의하지 않으면 equals의 값이 동일하더라도 서로 다른 객체가 되어버립니다. personSet이 "Alice"라는 내용의 객체를 가졌는지 확인하는 다음 코드는 false를 반환하게 되지요.
val personSet = hashSetOf(Person("Alice", 20, "Female"))
println(personSet.contains(Person("Alice", 20, "Female")))
// 출력값
false
이 때 hashCode를 정의하면 같은 속성을 가진 객체는 동일한 해시값을 갖게 되므로 동일한 객체라고 알아볼 수 있게 됩니다.
class Person(var name: String, var age: Int, var sex: String) {
override fun toString(): String {
return "Person(name=$name, age=$age, sex=$sex)"
}
override fun equals(other: Any?): Boolean {
if (other == null || other !is Person)
return false
return name == other.name && age == other.age && sex == other.sex
}
+ override fun hashCode(): Int {
+ return (name.hashCode() * 31 + age - sex.hashCode()) * 31
+ }
}
// 출력값
true
그런데 그냥 프로퍼티만을 가지는 단순한 클래스의 경우 이런 것들을 다 정의해주는 행위가 번거로운 일이기 때문에, 코틀린에서는 Data class라고 하는 새로운 클래스를 준비했습니다. Data class를 사용하면 위에 언급한 메소드를 자동으로 정의하여 주기 때문에 다음과 같이 간단하게 클래스를 만들수 있게 됩니다.
사용하는 법은 매우 간단한데요, class 앞에 data라는 접두어를 붙여주기만 하면 됩니다.
fun main() {
val person1 = Person("Alice", 20, "Female")
println(person1)
val person2 = Person("Bob", 22, "Male")
val person3 = Person("Bob", 22, "Male")
println(person2 == person3)
val personSet = hashSetOf(Person("Alice", 20, "Female"))
println(personSet.contains(Person("Alice", 20, "Female")))
}
data class Person(var name: String, var age: Int, var sex: String)
Data class에는 copy 메소드도 있습니다. copy는 이미 존재하는 인스턴스의 파라미터만을 바꿔서 새로운 객체를 만들어주는 메소드입니다. 이때 복사는 얕은복사로 이루어집니다.
fun main() {
val person4 = Person("Bob", 22, "Male")
val person5 = person4.copy(name = "Alice")
println(person5)
}
Data class는 객체가 소유한 데이터를 쪼개주는 Destructuring declarations 기능도 제공합니다. 다음과 같은 방식으로 사용할 수 있습니다.
fun main() {
val person6 = Person("Alice", 22, "Female")
val (name, age, sex) = person6
println("$name, $age years old $sex")
}
이렇게 해서 코틀린의 Data class에 대해 알아보았습니다.