코틀린은 특정 용도에 최적화된 특수 클래스들을 제공합니다. 데이터를 담아 나르는 데 최적화된 Data Class는 단어 하나만 붙이면 toString(), equals(), hashCode(), copy() 등의 메서드를 전부 자동 생성해 줍니다.
또한 상속받을 자식 클래스의 종류를 제한하여 when 문에서 절대적으로 안전한 분기 처리를 보장하는 Sealed Class (봉인 클래스)도 코틀린의 강력한 무기 중 하나입니다.
💡 핵심 기능: 보일러플레이트 코드 박멸기 (Data Class)
자바에서 DTO(데이터 전송 객체)를 만들 때 IDE의 자동 생성 기능을 이용해 수십 줄짜리 equals()와 toString()을 만들던 시절은 끝났습니다. 코틀린에서는 data 키워드 하나면 컴파일러가 모든 걸 보이지 않게 뒤에서 다 만들어줍니다.
🗂️ Data Class 의 자동 생성 마법
📊 코틀린 특수 클래스 비교표
클래스 종류
키워드
주요 목적과 특징
데이터 클래스
data class
데이터를 담고 전달하는 DTO 역할. 값의 비교(equals)와 예쁜 출력(toString) 자동 지원.
열거형 클래스
enum class
요일, 방향처럼 정해진 상수들의 집합. (자바의 enum과 동일)
봉인 클래스
sealed class
상속할 수 있는 자식의 종류를 컴파일러가 모두 알 수 있도록 파일을 봉인. when식과 환상의 짝꿍.
// 1. 데이터 클래스 (Data Class)
// 네트워크 요청 결과나 DB 데이터를 담는 껍데기(DTO)로 씁니다.
// toString(), equals(), hashCode(), 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 출력!
// 불변성을 지키기 위해, 일부 값만 바꾸면서 똑같은 구조의 새 객체를 복제할 수 있습니다.
val user3 = user1.copy(id = 2, username = "bob")
println(user3)
// === Sealed Class 와 when 식의 찰떡 궁합 ===
// 자식의 종류가 3개뿐이라는 것을 컴파일러가 완벽히 알고 있으므로 else 블록을 적을 필요가 없습니다.
val response: NetworkResult = NetworkResult.Success("서버 응답 데이터")
when (response) {
is NetworkResult.Success -> println("성공: " + response.data)
is NetworkResult.Error -> println("실패: " + response.exceptionMsg)
NetworkResult.Loading -> println("로딩 중...")
}
}