안드로이드 개발자의 창고
[16일차 Kotlin] Data Class 본문
출처 : 안드로이드 앱스쿨 2기 윤재성 강사님 수업 PPT
📖 Data Class란?
- DataClass는 매개체의 데이터(객체의 멤버)를 관리하는 용도로 사용하는 클래스이다.
- abstract, open, sealed, inner 클래스로 정의할 수 없다.
- 반드시 주 생성자를 가지고 있어야 한다.
- 주 생성자 작성을 강제하는 이유는 멤버 변수를 무조건 갖게 하기 위함이다.
-
Data Class 는 개발자의 개발 편리성을 위해 몇 가지 메서드가 자동으로 구현된다.
-
equals : 객체가 가지고 있는 변수를 모두 비교하는 메서드
-
hashCode : 객체를 구분하기 위한 고유한 정수값
-
copy : 객체를 복제하는 메서드
-
toString : 객체가 가지고 있는 변수의 값을 출력
-
componentN : 객체 분해
-
📖 객체 생성 예제 코드
일반 Class와 Data Class
class TestClass1(var a1:Int, var a2:Int){
var a3:Int = 0
init{
println("TestClass1의 init")
}
constructor(a1:Int, a2:Int, a3:Int) : this(a1, a2){
this.a3 = a3
}
fun testMethod1(){
println("TestClass1의 testMethod1입니다")
}
}
// DataClass
data class TestClass2(var a1:Int, var a2:Int){
var a3:Int = 0
init{
println("TestClass2의 init")
}
constructor(a1:Int, a2:Int, a3:Int) : this(a1, a2){
this.a3 = a3
}
fun testMethod2(){
println("TestClass2의 testMethod2 입니다")
}
}
생성자를 이용한 객체 생성
fun main() {
var obj1 = TestClass1(100,200)
var obj2 = TestClass2(100, 200)
// 멤버 사용
println("obj1.a1 : ${obj1.a1}")
println("obj1.a2 : ${obj1.a2}")
println("obj2.a1 : ${obj2.a1}")
println("obj2.a2 : ${obj2.a2}")
obj1.testMethod1()
obj2.testMethod2()
println("---------------------------------")
// 부생성자를 이용한 객체 생성
var obj3 = TestClass1(100,200,300)
var obj4 = TestClass2(100,200,200)
println("obj3.a1 : ${obj3.a1}")
println("obj3.a1 : ${obj3.a2}")
println("obj3.a1 : ${obj3.a3}")
println("obj4.a1 : ${obj4.a1}")
println("obj4.a2 : ${obj4.a2}")
println("obj4.a3 : ${obj4.a3}")
}
✔️ Console 출력 결과
equals(==)를 사용한 예제 코드
fun main(){
var obj5 = TestClass1(100,200,300)
var obj6 = TestClass1(100,200,300)
if(obj5 == obj6){
println("obj5와 obj6은 같은 객체 입니다")
} else {
println("obj5와 obj6은 다른 객체 입니다")
}
var obj7 = TestClass2(100, 200, 300)
var obj8 = TestClass2(100, 200, 300)
if(obj7 == obj8){
println("obj7과 obj8은 같은 객체 입니다")
} else {
println("obj7과 obj8은 다른 객체 입니다")
}
}
✔️ 코드 해석
- if(obj5 == obj6){ ... }
- 코틀린에서 == 를 사용하면 equals()메서드가 호출된다.
- obj5와 obj6은 TestClass1의 객체이다.
- data class 가 아닌 일반 클래스의 객체이므로 객체들의 ID가 같은지를 비교하게 된다.
- 따라서 "obj5와 obj6은 다른 객체 입니다"가 출력된다.
- if(obj7 == obj8){ ... }
- obj7과 obj8은 TestClass2의 객체이다.
- TestClass2는 data class이다.
- data 클래스는 주 생성자를 통해 정의된 멤버 변수의 값이 같은지를 비교한다.
- 따라서 "obj7과 obj8은 같은 객체 입니다"가 출력된다.
✔️ Console 출력 결과
copy()를 이용한 예제 코드
fun main(){
var obj9 = obj7.copy()
println("obj7.a1 : ${obj7.a1}")
println("obj9.a1 : ${obj9.a1}")
// obj9.a1의 값을 변경한다.
obj9.a1 = 1000
println("obj7.a1 : ${obj7.a1}")
println("obj9.a1 : ${obj9.a1}")
}
✔️ 코드 해석
- copy()는 data class에 있는 메서드로 객체를 복제하여 새로운 객체를 만든다.
- var obj9 = obj7.copy()
- obj7은 TestClass2(data class)의 객체로 a1=100, a2=200, a3=300의 값이 들어있다.
- obj7을 copy()를 이용하여 깊은 복사를 한다.
- 깊은 복사 : 객체를 복사할 때 객체의 전체 값을 복사
- 얕은 복사 : 객체를 복사할 때 객체의 주소 값을 복사
- 깊은 복사를 한 obj9의 a1 값을 바꿔도 obj7의 a1 값은 바뀌지 않는다.
- 따라서 obj7의 a1 값은 100, obj9의 a1 값은 1000으로 출력된다.
- 깊은 복사가 아닌 얕은 복사를 원한다면 copy()를 사용하지 않고 obj9 = obj7 라고 코드를 작성하면 된다.
componentN을 이용한 예제 코드
fun main(){
val num1 = obj7.component1()
val num2 = obj7.component2()
println("num1 : $num1")
println("num2 : $num2")
println("---------------------------------")
val (num10, num11) = obj7
println("num10 : $num10")
println("num11 : $num11")
}
✔️ 코드 해석
- data class 를 통해 만든 객체는 주 생성자에 정의한 멤버 변수를 componentN 메서드로 값을 받아올 수 있다.
- val (num10, num11) = obj7
- 객체 분해 : 주 생성자를 통해 정의된 맴버 변수의 값을 하나씩 추출하여 좌측에 작성한 변수들에 순서대로 담아준다.
- 이 때, componentN 메서드들을 호출하여 값을 전달한다.
'Computer > Kotlin' 카테고리의 다른 글
[16일차 Kotlin] 중첩 클래스 (0) | 2023.05.19 |
---|---|
[16일차 Kotlin] Generic (0) | 2023.05.18 |
[16일차 Kotlin] Companion (0) | 2023.05.18 |
[15일차 Kotlin] 인터페이스(Interface) (0) | 2023.05.17 |
[15일차 Kotlin] 추상화(abstract) (0) | 2023.05.17 |