minstudio

13. 특수 목적 클래스 (Data, Enum, Sealed Class)

데이터만 담는 용도의 클래스(DTO 등)를 만들 때는 Data Class를 씁니다. 한 줄만 적으면 toString(), equals(), copy() 메서드가 전부 자동 생성되어 보일러플레이트 코드를 박멸합니다.

그 외에도 상태값을 열거하는 Enum Class, 상속 가능한 자식 클래스의 종류를 제한하여 when 식에서 완벽한 처리를 보장하는 Sealed Class가 있습니다.

// 1. 데이터 클래스 (Data Class)
// 데이터 보관 목적. equals, hashCode, toString, copy 가 자동 생성됨.
data class UserDto(val id: Int, val username: String, var email: String)

// 2. 봉인 클래스 (Sealed Class)
// 상속받는 자식들을 동일한 파일 내로 강제 제한하여, 종류를 한정 짓습니다.
sealed class NetworkResult {
    data class Success(val data: String) : NetworkResult()
    data class Error(val exceptionMsg: String) : NetworkResult()
    object Loading : NetworkResult() // 상태만 나타내면 object 사용 가능
}

fun main() {
    // Data Class 활용
    val user1 = UserDto(1, "alice", "alice@test.com")
    val user2 = UserDto(1, "alice", "alice@test.com")
    
    // toString()이 자동으로 오버라이딩 되어 예쁘게 출력됨
    println(user1) 
    // equals()가 내부 값들을 비교하도록 오버라이딩 되어 있음 (주소 비교 아님)
    println("두 유저가 같은가? " + (user1 == user2)) // true
    
    // copy() 메서드로 일부 값만 바꾸면서 불변 객체 복제
    val user3 = user1.copy(id = 2, username = "bob")
    println(user3)

    // Sealed Class와 when의 찰떡 궁합
    // Result의 자식이 3개뿐이라는 것을 컴파일러가 알아서, else가 필요 없음!
    val response: NetworkResult = NetworkResult.Success("서버 응답 데이터")
    when (response) {
        is NetworkResult.Success -> println("성공: " + response.data)
        is NetworkResult.Error -> println("실패: " + response.exceptionMsg)
        NetworkResult.Loading -> println("로딩 중...")
    }
}
13. 특수 목적 클래스 (Data, Enum, Sealed Class) | Minstudio