데이터 클래스 및 봉인 클래스
값 기반 동등성과 copy()에는 데이터 클래스를 사용하고, 모든 경우를 처리하는 형식 계층과 깔끔한 상태 모델링에는 봉인 클래스를 사용합니다.
데이터 클래스 및 봉인 클래스은(는) CoddyKit의 무료 Android Academy 강의입니다. 이것은 4개 중 3번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 Android Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
데이터 클래스란 무엇인가요?
Kotlin의 데이터 클래스는 주된 목적이 데이터를 저장하는 클래스입니다. 컴파일러가 다음과 같은 유용한 메서드를 자동으로 생성합니다.
equals()— 두 인스턴스를 값으로 비교합니다hashCode()— 속성을 기반으로 일관된 해시를 생성합니다toString()— 읽기 쉬운 문자열 표현을 제공합니다copy()— 수정된 복사본을 만듭니다- 구조 분해를 지원합니다
데이터 클래스 선언
class 앞에 data 키워드를 추가합니다. 모든 속성은 주 생성자에 있어야 합니다.
data class User(val id: Int, val name: String, val email: String)
fun main() {
val u1 = User(1, "Alice", "alice@example.com")
val u2 = User(1, "Alice", "alice@example.com")
println(u1) // User(id=1, name=Alice, email=alice@example.com)
println(u1 == u2) // true (value equality)
println(u1 === u2) // false (different objects)
}copy() — 필드 하나 수정하기
copy()는 일부 속성이 변경된 새 인스턴스를 만듭니다. 원본은 수정되지 않습니다(불변성).
data class Product(val name: String, val price: Double, val inStock: Boolean)
fun main() {
val original = Product("Laptop", 999.0, true)
// Only change the price; keep everything else
val onSale = original.copy(price = 799.0)
println(original) // Product(name=Laptop, price=999.0, inStock=true)
println(onSale) // Product(name=Laptop, price=799.0, inStock=true)
}구조 분해 선언
데이터 클래스는 구조 분해를 지원합니다. 컴파일러가 생성한 componentN() 함수를 사용해 속성을 변수로 풀어낼 수 있습니다.
data class Point(val x: Int, val y: Int)
fun main() {
val point = Point(10, 20)
// Destructure into separate variables
val (x, y) = point
println("x=$x, y=$y") // x=10, y=20
// Also works in for loops with maps
val scores = mapOf("Alice" to 95, "Bob" to 88)
for ((name, score) in scores) {
println("$name: $score")
}
}봉인 클래스란?
봉인 클래스는 제한된 클래스 계층 구조입니다. 모든 하위 클래스는 같은 파일에 정의되어야 합니다. 따라서 가능한 타입 집합을 컴파일 시점에 알 수 있습니다.
네트워크 결과, UI 상태 또는 탐색 이벤트처럼 유한한 상태 집합을 표현할 때 봉인 클래스를 사용합니다.
봉인 클래스 문법
하위 클래스를 클래스 내부에 직접 선언하거나 같은 파일에 선언합니다.
sealed class NetworkResult<out T> {
data class Success<T>(val data: T) : NetworkResult<T>()
data class Error(val message: String, val code: Int = 0) : NetworkResult<Nothing>()
object Loading : NetworkResult<Nothing>()
}
fun handle(result: NetworkResult<String>) {
when (result) {
is NetworkResult.Success -> println("Data: ${result.data}")
is NetworkResult.Error -> println("Error ${result.code}: ${result.message}")
NetworkResult.Loading -> println("Loading...")
}
}봉인 클래스 + when(완전성)
봉인 클래스의 강력한 기능은 when이 모든 경우를 처리한다는 것입니다. 컴파일러가 모든 하위 타입을 처리하도록 강제하므로 빠뜨리는 경우가 없습니다.
sealed class UiState {
object Loading : UiState()
data class Success(val message: String) : UiState()
data class Error(val error: String) : UiState()
}
fun render(state: UiState): String = when (state) {
is UiState.Loading -> "Showing spinner"
is UiState.Success -> "Show: ${state.message}"
is UiState.Error -> "Error: ${state.error}"
// Compiler error if you remove any branch!
}
fun main() {
println(render(UiState.Loading))
println(render(UiState.Success("Loaded!")))
}봉인 클래스와 열거형 비교
둘 다 고정된 값 집합을 표현하지만 차이점은 다음과 같습니다.
- 열거형 — 각 상수는 하나의 인스턴스이며, 각 변형에 추가 데이터를 담을 수 없음
- 봉인 클래스 — 각 변형이 서로 다른 데이터를 가질 수 있고, 클래스나 객체가 될 수 있음
변형에 데이터가 필요하지 않으면 열거형을 사용합니다. 변형마다 서로 다른 속성이 필요하면 봉인 클래스를 사용합니다.
객체 선언(싱글턴)
object는 싱글턴을 만듭니다. 즉, 인스턴스 하나만 지연 생성하며 스레드로부터 안전합니다.
object AppConfig {
const val BASE_URL = "https://api.example.com"
const val TIMEOUT = 30L
fun buildUrl(path: String) = "$BASE_URL/$path"
}
fun main() {
println(AppConfig.BASE_URL) // https://api.example.com
println(AppConfig.buildUrl("users")) // https://api.example.com/users
}동반 객체
동반 객체는 클래스 내부에 존재하며 클래스 수준의 멤버를 제공합니다(Java의 static과 유사합니다). 팩토리 메서드에 흔히 사용됩니다.
class Token private constructor(val value: String) {
companion object {
fun create(raw: String): Token {
val cleaned = raw.trim()
require(cleaned.isNotEmpty()) { "Token must not be blank" }
return Token(cleaned)
}
}
}
fun main() {
val token = Token.create(" abc123 ")
println(token.value) // abc123
}실제 앱에서 사용하는 데이터 클래스
데이터 클래스와 봉인 클래스를 결합해 상태를 깔끔하게 모델링합니다.
data class Post(val id: Int, val title: String, val body: String)
sealed class PostState {
object Loading : PostState()
data class Loaded(val posts: List<Post>) : PostState()
data class Failed(val reason: String) : PostState()
}
fun showState(state: PostState) = when (state) {
PostState.Loading -> println("Fetching posts...")
is PostState.Loaded -> println("${state.posts.size} posts loaded")
is PostState.Failed -> println("Failed: ${state.reason}")
}
fun main() {
showState(PostState.Loaded(listOf(
Post(1, "Hello", "World"),
Post(2, "Kotlin", "Rocks")
)))
}빠른 확인
봉인 클래스가 일반 추상 클래스와 다른 점을 가장 잘 설명하는 문장은 무엇인가요?
복습: 데이터 클래스와 봉인 클래스
이제 Kotlin의 강력한 도구 두 가지를 익혔습니다.
- 데이터 클래스 — 값 기반 동등성,
copy(), 구조 분해, 자동 생성되는toString() - 봉인 클래스 — 유한한 타입 계층 구조, 모든 경우를 처리하는
when, 각 변형이 자체 데이터를 가질 수 있음 - 객체 — 싱글턴, 팩토리 메서드에 사용하는 동반 객체
이 패턴들을 함께 사용하면 Java의 반복적인 코드를 줄이고 깔끔하고 안전하게 상태를 모델링할 수 있습니다.
자주 묻는 질문
“데이터 클래스 및 봉인 클래스” 강의는 무료인가요?
네 — “데이터 클래스 및 봉인 클래스” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 Android Academy 강의 전체를 잠금 해제할 수 있습니다. Android Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“데이터 클래스 및 봉인 클래스”에서 뭘 배우나요?
값 기반 동등성과 copy()에는 데이터 클래스를 사용하고, 모든 경우를 처리하는 형식 계층과 깔끔한 상태 모델링에는 봉인 클래스를 사용합니다. 브라우저에서 직접 실행하는 실습 코드로 Android Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
Android Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 Android Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 3번째 강의입니다.
“데이터 클래스 및 봉인 클래스” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 Android Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 Android Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 널 안전성
- 클래스 및 객체
- 데이터 클래스 및 봉인 클래스
- 확장 함수 및 고차 함수