본문 바로가기

Study/Kotlin Study

[Kotlin] data 클래스

+ 항공대학교 김철기 교수님의 객체 지향 프로그래밍 과목 내용를 정리한 글입니다.

클래스의 동등성

일반 클래스의 동등성 비교를 위해서는 equals()hashCode()의 커스텀 구현이 필요하다.

 

< 일반 클래스의 동등성 비교 >

class Person(val firstName: String, val lastName: String, val age: Int)

fun main() {
    val person1 = Person("John", "Doe", 25)
    val person2 = Person("John", "Doe", 25)
    val person3 = person1

    println(person1 == person2) // false
    println(person1 == person3) // true
}

 

 

< equals(), hashCode()를 이용한 일반 클래스의 동등성 비교 >

class Person(val firstName: String, val lastName: String, val age: Int) {
    override fun equals(other: Any?): Boolean {
        if (other !is Person) return false
        return other.firstName == firstName && other.lastName == lastName && other.age == age
    }

    override fun hashCode(): Int {
        var hash = firstName.hashCode()
        hash = lastName.hashCode() + 31 * hash
        hash = age.hashCode() + 31 * hash
        return hash
    }
}

fun main() {
    val person1 = Person("John", "Doe", 25)
    val person2 = Person("John", "Doe", 25)
    val person3 = person1

    println(person1 == person2) // true
    println(person1 == person3) // true
}

data 클래스의 동등성

data 클래스생성자 파라미터만을 프로퍼티로 가지는 클래스로 프로퍼티가 동일하면 자동으로 동등성 체크를 해준다.

 

< data 클래스를 이용한 동등성 비교 >

data class Person(val firstName: String, val lastName: String, val age: Int)

fun main() {
    val person1 = Person("John", "Doe", 25)
    val person2 = Person("John", "Doe", 25)
    val person3 = person1

    println(person1 == person2) // true
    println(person1 == person3) // true
}

 

< data 클래스의 생성자 파라미터에 일반 클래스형 데이터가 들어올 경우 >

class Person(val firstName: String, val lastName: String, val age: Int)

data class MailBox(val address: String, val person: Person)

fun main() {
    val mailbox1 = MailBox("Unknown", Person("John", "Doe", 25))
    val mailbox2 = MailBox("Unknown", Person("John", "Doe", 25))

    println(mailbox1 == mailbox2) // false
}

 

< data 클래스의 생성자 파라미터에 data 클래스형 데이터가 들어올 경우 >

data class Person(val firstName: String, val lastName: String, val age: Int)

data class MailBox(val address: String, val person: Person)

fun main() {
    val mailbox1 = MailBox("Unknown", Person("John", "Doe", 25))
    val mailbox2 = MailBox("Unknown", Person("John", "Doe", 25))

    println(mailbox1 == mailbox2) // true
}

data 클래스의 toString()

data 클래스는 toString()도 자동으로 구현해준다.

 

< 일반 클래스의 인스턴스 출력 >

class Person(val firstName: String, val lastName: String, val age: Int)

fun main() {
    val person = Person("John", "Doe", 25)

    println(person) // Person@12a3a380 (해쉬 코드와 함께 출력)
}

 

< data 클래스의 인스턴스 출력 >

data class Person(val firstName: String, val lastName: String, val age: Int)

fun main() {
    val person = Person("John", "Doe", 25)

    println(person) // Person(firstName=John, lastName=Doe, age=25)
}

data 클래스의 copy() 함수

data 클래스를 복사해주는 함수이다.

+ 일부 프로퍼티의 변경도 지원한다.

 

data class Person(val firstName: String, val lastName: String, val age: Int)

fun Person.show() {
    println("$firstName $lastName : $ $age")
}

fun main() {
    val person = Person("John", "Doe", 25)

    person.show() // John Doe : $ 25
    person.copy().show() // John Doe : $ 25
    person.copy(lastName = "Smith").show() // John Smith : $ 25
    person.copy(firstName = "Jane", age = 30) .show() // Jane Doe : $ 30
}

Pair와 Triple 데이터 클래스

= 임의의 값 2개 혹은 3개를 가지는 표준 데이터 클래스

 

fun main() {
    val pair = Pair(1, "two") // val pair = 1 to "two" 로 대체 가능
    
    println(pair.first + 1) // 2
    println(pair.second) // two

    val triple = Triple(1, "two", false)
    
    println(triple.first + 2) // 3
    println(triple.second) // two
    println(triple.third) // false
}

구조 분해 선언

data 객체의 프로퍼티들을 여러 변수에 하나의 문장으로 대입한다.

 

< 예시 1 >

data class Person(val firstName: String, val lastName: String, val age: Int)

fun main() {
    val person = Person("John", "Doe", 25)

    val (firstName, familyName, age) = person

    if (age >= 18) {
        println("$firstName $familyName is adult")
    }
}

 

< 예시 2 : 변수의 개수를 인자 프로퍼티 수와 다르게 대입 >

data class Person(val firstName: String, val lastName: String, val age: Int)

fun main() {
    val person = Person("John", "Doe", 25)

    val (_, familyName, age) = person
    // _는 인자를 받지 않는다는 의미

    if (age >= 18) {
        println("Mr.$familyName is adult.") // Mr.Doe is adult.
    }
}

for 루프에서의 구조 분해

for 루프에서 구조 분해는 유용하게 사용될 수 있다.

 

< 구조 분해 사용 X > 

fun main() {
    val array = arrayOf(1 to "one", 2 to "two", 3 to "three")

    for (elem in array) {
        println("${elem.first} -> ${elem.second}")
    }
}

 

< 구조 분해 사용 O >

fun main() {
    val array = arrayOf(1 to "one", 2 to "two", 3 to "three")

    for ((number, name) in array) {
        println("$number -> $name")
    }
}

'Study > Kotlin Study' 카테고리의 다른 글

[Kotlin] 봉인된 클래스  (1) 2023.11.14
[Kotlin] 부호 없는 정수  (0) 2023.11.14
[Kotlin] enum 클래스  (1) 2023.11.13
[Kotlin] 인터페이스  (3) 2023.11.02
[Kotlin] 추상 클래스와 추상 멤버  (0) 2023.11.02