Byzz91
7/21/2019 - 8:40 AM

코틀린 데이터 클래스 예제

코틀린 데이터 클래스 예제

package my.demo

/**
 * 코틀린의 최상위 클래스인 `Any`
 */

/**
 * 데이터 클래스란!?
 *
 * 클래스가 메서드 없이 프로퍼티만을 가질 때 사용할 수 있는 클래스이다.
 *
 * 코틀린 개발자들은 데이터 클래스의 모든 프로퍼티를 읽기 전용(`val` 타입)으로 만들어
 * 불변 클래스(`Immutable Class`)로 사용할 것은 권한다. HashMap 등의 컨테이너에 데이터 클래스를 사용할 경우 `불변성`이 필수 요소이기
 * 때문이다. = copy()
 */

data class Sample(val name: String, val postalCode: Int)

/**
 * `data`를 붙이는 이유는, 코틀린에서 데이터 클래스에게 제공하는 혜택들이 있기 때문이다.
 * 바로 **필수 메서드 자동 생성** 기능이다.
 *
 * - toString()
 *  - > 인스턴스를 문자열로 변환해서 반환하는 역할. 코틀린에서는 클래스명과 해시코드를 조합해서 만들어진 문자열을 반환
 * - equals()
 *  - > 자바에서는 `==` 연산 대신 `equals()` 메서드를 호출하여 두 객체의 값이 동일한지 확인하도록 한다.
 *  - > 하지만 코틀린에서는 `==` 연산과 `equals()` 연산이 같다.
 * - hashCode()
 * - copy()
 *  - > copy() 메서드는 객체를 복사하면서 일부 프로퍼티의 값을 변경할 수 있도록 해준다. 원본 객체는 복사된 객체의 수정 여부에 전혀 영향을 받지 않는다.
 */

class Client(val name: String, val posatalCode: Int) {
    override fun equals(other: Any?): Boolean {
        if (other == null || other !is my.demo.Client) return false

        /**
         * `is` 연산자는 특별한 기능
         *
         * 참조 객체가 연산에 사용된 타입과 일치할 경우 연산에 사용된 참조 객체를 해당 타입으로 자동 변환 (Smart Cast)
         */
        return name == other.name && posatalCode == other.posatalCode
    }

    /**
     * JVM 언어에는 `equals()`가 true를 반환하는 두 객체는 반드시 hashCode()를 반환해야 한다 라는 제약이 있다
     * 따라서 equals()를 오버라이드 할 경우 반드시 hashCode() 메서드도 함께 오버라이드 해야한다.
     *
     * data class는 모든걸 자동으로 완성해준다.
     */
    override fun hashCode(): Int = name.hashCode() * 31 + posatalCode
}

data class Client2(val name: String, val postalCode: Int)

fun main(argv: Array<String>) : Unit {
    val client = Client("Monguse", 1234)
    val client2 = Client("Monguse", 1234)
    println(client == client2)
    println(client.equals(client2))

    /**
     * HashSet 객체에서 값이 Client 객체를 찾지 못한다
     * HashSetOf(); 클래스는 각 객체의 해시코드를(Hash Code)를 우선적으로 검사하기 때문이다.
     */
    val clientSet: HashSet<Client> = hashSetOf<Client>(Client("Monguse", 1234))
    println(clientSet.contains(Client("Monguse", 1234)))

    /**
     * copy() 예제
     */
    val client3 = Client2("Monguse", 1234)
    val client4 = client3.copy(postalCode = 1236)
    println(client3)
    println(client4)
}