코테 언어를 Java로 바꾸고! 스프링을 자바로 공부하고! 자바를 계속해서 사용하다 보니 안드로이드를 개발하는데 코틀린이라는 언어에 대한 고마움이 샘솟고 있다.
그 중 가장 대표적인게 Data Class 였다. 매번 자바에서 toString() 만들어주는게 얼마나 코드가 많던지… 하지만 record라고 JDK 16에서 정식 기능으로 포함된 Data class의 역할을 한다니까 참으로 다행이다.
코드도 data class 형식이랑 완전 똑같던데
record Example(int x, int y) {}
암튼 오늘은 코틀린의 Data Class에 대해 정리해보겠다.
Data class
코틀린의 Data class는 생성자부터 getter & setter, canonical method인 toString(), hashCode(), equals() 와 , copy(), componentN() 까지 생성해준다.
기본
data class Example(
val name : String,
val number : Int
)
위의 코드와 같이 class 앞에 data 키워드를 붙여주면 된다! Java에서 클래스 만들어줄 때처럼 getter와 setter를 쓰지 않아도 자동으로 만들어준다.
그 뒤 사용할 때에는 객체를 만들어 사용해주면 됨!
val exampleOne = Example("al", 0)
val exampleTwo = Example("packa", 1)
제한사항
- 기본 생성자에는 최소 하나의 프로퍼티가 있어야 한다.
- 기본 생성자의 프로퍼티는 val이나 var여야만 한다.
- 데이터 클래스는 abstract, open, sealed, inner 등 키워들을 붙일 수 없음
- 상속받을 수 없다. 단 sealed 클래스는 상속받을 수 있으며, 인터페이스는 구현할 수 있음(v1.1이후)
메소드
Canonical Methods
Any에 선언된 메소드이다. (참고로 Any는 자바의 Object 처럼 코틀린에서 모든 객체의 조상이 되는 객체)
코틀린의 모든 인스턴스가 갖고 있는 메소드를 뜻한다고 한다.
이런식으로 정의되어 있다.
public open class Any {
public open operator fun equals(other: Any?): Boolean
public open fun hashCode(): Int
public open fun toString(): String
}
toString()
일반 클래스의 경우 toString() 사용시 주소값이 나오지만
data class는 인스턴스의 프로퍼티를 문자열로 출력해준다.
fun main(){
val exampleData = ExampleData("알파카")
print(exampleData.toString())
}
// 출력 -> ExampleData(name=알파카)
equals(other: Any?), hashCode()
동등성 연산 → 동일한 값을 가진 인스턴스인지 비교하는 것.
동일성 연산 → 주소값이 같은 인스턴스인지 비교하는 것.
일반 클래스의 경우 인스턴스의 주소값을 비교하지만
data class의 경우 값이 일치하는지를 비교해준다!
일반 클래스의 경우 값이 equals를 동등성을 비교하기 위해 사용하려면 equals()와 hashCode()를 오버라이딩 해줘야 한다.
fun main(){
val exampleData1 = ExampleData("알파카")
val exampleData2 = ExampleData("알파카")
println(exampleData1.equals(exampleData2))
println(exampleData1.hashCode())
println(exampleData2.hashCode())
println(exampleData1.hashCode() == exampleData2.hashCode())
}
// 출력 -> true
// -> 50265908
// -> 50265908
// -> true
copy() 메소드
종종 데이터 클래스의 복사를 하고 싶을 때가 있다.
copy() 메소드를 통해 원하는 파라미터를 오버라이딩해서 데이터 클래스의 새로운 인스턴스를 생성할 수 있게 한다.
즉, 얕은 복사와 깊은 복사 중에서도 깊은 복사에 해당하는 copy라고 보면 된다.
이게 유용한게 data class의 프로퍼티가 많은데 특정 변수만 변경하고자 할 경우 이걸 몰랐을 때는 일일이 다 적고 써줬는데 copy를 알게 되고, 나의 코드가 간결해졌다.
data class ExampleData(
val name : String,
val age : Int,
val check : Boolean
)
//기존 사용
val value = ExampleData("알파카", 28, true)
val newValue = ExampleData(first.name, 29, first.check)
//copy 사용
val newValue = value.copy(age = 29)
componentN()
componentN()을 통해 아래와 같이 구조분해가 가능하다.
data class ExampleData(
val name : String,
val age : Int,
val check : Boolean
)
val example: ExampleData = ExampleData("알파카", 28, true)
val (name, age, check) = example //변수를 선언함과 동시에 example의 여러 컴포넌트로 초기화 한다.
컴파일 시
val (name, age, check) = example
->
val name = example.component1()
val age = example.component2()
val check = example.component3()
하지만 주의해야 할 점이 , 맨 앞의 다섯 개 원소에 대해서만 componentN을 제공한다.
'Language > kotlin' 카테고리의 다른 글
[Kotlin] Coroutine (0) | 2024.07.23 |
---|---|
[Kotlin] 스코프함수(Scope function) (1) | 2024.07.05 |
[Kotlin] 추상 클래스 & 인터페이스 (0) | 2024.06.10 |
[kotlin] 정렬 정리 (0) | 2023.12.19 |
[kotlin] 배열 (0) | 2023.12.15 |