Coding Memo
Kotlin 데이터 클래스 본문
Java에는 없는 좀 특이한 클래스를 제공한다.
데이터만을 가지고 있는 클래스를 data class로 만들 수 있다.
아래 링크는 공식문서이다.
https://kotlinlang.org/docs/reference/data-classes.html
Data Class
데이터클래스는 다음과 같은 조건을 충족해야 한다.
- 기본 생성자는 적어도 하나의 파라미터를 가져야 한다.
- 모든 기본 생성자의 파라미터는 val이나 var으로만 선언되어야 한다.
- abstract, open, sealed or inner가 될 수 없다.
데이터 클래스를 5가지 기능으로 나누어본다면 다음과 같다.
- equals()
- hashcode()
- copy()
- componentX()
- toString()
선언의 예시는 다음과 같다. (공식 문서에 있는 예시를 그대로 가져왔다.)
data class User(val name: String, val age: Int)
equals
클래스 내의 속성 값을 비교한다.
'=='와 같은 기능을 한다.
(약간 초점은 벗어났지만 '==='의 기능도 함께 알아보려고 다음과 같은 예시를 만들었다.)
주의할 점은 Java와는 참조를 하여 비교할 때 다르다.
내부 속성 데이터가 값이 같아도,
객체 자체를 비교하려고 '=='를 사용했을 경우,
자바에서는 객체 자체 (object)를 비교하기 때문에 false가 나오고
코틀린은 반대로 true가 나온다.
자바에서의 코드
public class Test {
public static void main(String args[]) {
User u1 = new User("Mike", 21);
User u2 = new User("Mike", 21);
if (u1 == u2) {
System.out.println("Same");
}
else {
System.out.println("Different");
}
}
}
class User {
String name;
int age;
User(String name, int age) {
this.name = name;
this.age = age;
}
}
fun main() {
val p1 = User("Mike", 21)
val p2 = User("Mike", 21)
val p3 = User("John", 21)
val p4 = p1
if (p1 == p2) { //p1.equals(p2) 와 같다.
println("p1 and p2 are same")
}
else {
println("p1 and p2 are not same")
}
if (p1.equals(p3)) { //p1 == p3와 같다.
println("p1 and p3 are same")
}
else {
println("p1 and p3 are not same")
}
if (p1 === p2) {
println("p1 and p2 have same address")
}
else {
println("p1 and p2 do not have same address")
}
if (p1 === p4) {
println("p1 and p4 have same address")
}
else {
println("p1 and p4 do not have same address")
}
}
data class User(val name: String, val age: Int)
p1 == p2 가 Java에서는 false로, 코틀린에서는 true로 나오는 것을 확인할 수 있다.
참고: '==='은 주소 값을 비교하는 연산자이다.
hashCode
객체의 메모리 주소를 이용해서 hashcode를 생성하여 그 값을 리턴하는 함수이다.
결국은 equals와 똑같이 비교할 때 쓰일 수 있다.
공식문서에서도 equals()와 hashCode()를 묶어놓았다.
fun main() {
val p1 = User("Mike", 21)
val p2 = User("Mike", 21)
val p3 = User("John", 21)
val p4 = p1
println(p1.hashCode())
println(p2.hashCode())
println(p3.hashCode())
println(p4.hashCode())
}
data class User(val name: String, val age: Int)
copy / toString
말 그대로 객체 내의 데이터 값을 복사하여 객체를 반환하는 함수이다.
조금 특이한 점은 기본적으로는 모든 속성을 복사하는데 직접 일부 값을 변경하여 복사를 할 수도 있다.
toString은 내부 데이터를 String으로 바꾸어주는 함수이다.
fun main() {
val p1 = User("Mike", 21)
val p2 = p1.copy()
val p3 = p1.copy(name = "John") //name이 첫 번째 인자기 때문에 'name ='를 반드시 쓰지는 않아도 된다.
val p4 = p1.copy(age = 23)
println(p2.toString())
println(p1.toString())
println(p3.toString())
println(p4.toString())
}
data class User(val name: String, val age: Int)
주소 값은 어떻게 될까? -> 값이 같으므로 heap 영역의 메모리 주소 값이 같다.
(단순히 "Mike"라는 같은 값을 가지고 있기 때문에 p1.name 과 p2.name이 가리키는 주소값이 같을 뿐이지, 계속 공유하기 때문에 p1.name 값을 변경하면 p2.name의 값까지 변경되는 것은 아니다. -> p1과 p2는 다른 객체이다.)
fun main() {
val p1 = User("Mike", 21)
val p2 = p1.copy()
if (p1 === p2) {
println("주소값 같음")
}
else {
println("주소값 다름")
}
if (p1.name === p2.name) {
println("주소값 같음")
}
else {
println("주소값 다름")
}
p1.name = "John"
println(p1.name)
println(p2.name)
}
data class User(var name: String, var age: Int)
componentX
X번째 있는 속성(component)의 값을 얻어오는 함수이다.
순서가 달라지면 반환되는 값도 달라지게 되므로 주의!
fun main() {
val p1 = User("Mike", 21)
println(p1.component1())
println(p1.component2())
}
data class User(val name: String, val age: Int)
'Language > Kotlin' 카테고리의 다른 글
Kotlin Set (Collections) (0) | 2021.01.11 |
---|---|
Kotlin 리스트 (Collections) (0) | 2021.01.10 |
Kotlin 열거형 클래스 (0) | 2021.01.08 |
Kotlin 중첩 / 내부 클래스 (0) | 2021.01.08 |
Kotlin 함수 파라미터 (0) | 2021.01.06 |