Kotlin의 sealed class와 interface — 개념, 문법 및 활용

저자: IT Sectr 게시일: 2026-06-20 읽는 시간: 11 분

sealed class와 sealed interface는 Kotlin에서 제한된 유형 계층 구조를 위한 메커니즘으로, 가능한 모든 하위 클래스가 컴파일 타임에 알려집니다. 일반 추상 클래스와 달리 sealed class는 when 표현식에서 모든 변형의 완전한 처리를 보장합니다. JetBrains Kotlin Language Guide(2026) 문서에 따르면, sealed 유형은 Kotlin 프로젝트에서 상태, UI 화면 및 결과 유형을 모델링하는 기초입니다.

핵심 요점

  • sealed — 모든 하위 클래스가 컴파일 타임에 알려진 제한된 계층 구조
  • when — 필수 else 블록 없이 모든 하위 클래스의 완전한 처리
  • sealed interface — 상속 제한 없이 유연한 계층 구조를 위해 Kotlin 1.5에서 추가됨
  • 컴파일 — sealed 유형에 대한 불완전한 when에서 컴파일 오류
  • 계층 구조 — 모든 하위 클래스는 동일한 파일 또는 sealed 클래스 내에 있어야 함

sealed class와 sealed interface란?

sealed class는 제약이 있는 추상 클래스입니다. 모든 직접 하위 클래스는 sealed class 자체와 동일한 파일에서 선언되어야 합니다. 이 제약으로 인해 계층 구조가 닫히며(sealed), 파일 외부의 코드는 새 하위 클래스를 추가할 수 없습니다.

sealed interface는 Kotlin 1.5에서 추가되었으며, 동일한 보장을 제공하지만 인터페이스의 유연성을 갖습니다. sealed interface는 하나의 파일에서 여러 클래스, 객체 또는 다른 인터페이스에 의해 구현될 수 있습니다. sealed class와 달리 sealed interface에는 단일 상속 제한이 없으며, 클래스는 여러 sealed 인터페이스를 동시에 구현할 수 있습니다.

Kotlin Evolution and Roadmap(2026)에 따르면, sealed interface는 보다 유연한 모델링을 위해 커뮤니티 요청으로 추가되었습니다. 주요 동기는 다중 클래스 상속 없이 독립적인 유형 계층 구조를 결합하는 능력입니다.

sealed class 문법

sealed class의 선언은 class 앞에 sealed 한정자로 시작합니다. 하위 클래스는 동일한 파일에서 선언됩니다.

kotlin
sealed class NetworkResult {
    data class Success(val data: String) : NetworkResult()
    data class Error(val message: String) : NetworkResult()
    object Loading : NetworkResult()
}

sealed class의 각 하위 클래스는 고유한 속성과 메서드를 가질 수 있습니다. Loading은 싱글톤(object)이고, Success와 Error는 매개변수가 있는 data class입니다. 컴파일러는 세 가지 변형을 모두 알고 when에서 사용될 때 완전성을 확인합니다.

중첩된 sealed 클래스

sealed 클래스는 중첩될 수 있어, 타입 안전성을 잃지 않으면서 복잡한 데이터 모델을 위한 다중 레벨 계층 구조를 만듭니다.

kotlin
sealed class UiState {
    object Idle : UiState()
    object Loading : UiState()
    data class Content(val items: List<Item>) : UiState()
    data class Error(val exception: Throwable) : UiState()
}

sealed interface 문법(Kotlin 1.5+)

sealed interface는 sealed class와 유사하게 선언되지만, 하나의 클래스에서 여러 sealed 인터페이스를 구현할 수 있습니다.

kotlin
sealed interface Action
sealed interface Loggable

data class Navigate(val route: String) : Action, Loggable
data class ShowToast(val text: String) : Action
object GoBack : Action, Loggable

Navigate 클래스는 Action과 Loggable이라는 두 개의 sealed 인터페이스를 동시에 구현합니다. 이는 단일 상속 제한으로 인해 sealed class에서는 불가능합니다. sealed interface는 독립적인 계층 구조를 결합하는 유연성을 제공합니다.

sealed class 대신 sealed interface를 선택하는 경우

sealed interface는 계층 구조가 공유 상태나 생성자를 필요로 하지 않을 때 선호됩니다. JetBrains Kotlin Guidelines(2026)에 따르면, 공통 생성자가 필요하지 않은 모든 새 계층 구조에서는 기본적으로 sealed interface를 사용해야 하며, 이는 향후 확장을 위해 코드를 더 유연하게 만듭니다.

when에서의 완전한 처리

sealed 유형의 주요 장점은 when 표현식에서의 완전한(exhaustive) 처리입니다. 컴파일러는 가능한 모든 하위 클래스가 포함되었는지 확인합니다.

kotlin
fun handleResult(result: NetworkResult): String = when (result) {
    is NetworkResult.Success -> "Data: ${result.data}"
    is NetworkResult.Error -> "Error: ${result.message}"
    is NetworkResult.Loading -> "Loading..."
    // else는 필요하지 않음 — 컴파일러가 모든 변형이 포함되었음을 알고 있음
}

만약 개발자가 sealed 계층 구조에 새 하위 클래스를 추가했지만 when에서 처리하는 것을 잊었다면, 컴파일러가 오류를 발생시킵니다. 이는 else 분기를 사용하는 개방형 계층 구조에서는 사용할 수 없는 유형 수준의 안전성입니다.

Google Android Developers(2026)에 따르면, sealed 클래스는 Jetpack Compose에서 UI 상태를 모델링하는 권장 방법입니다. when의 완전한 검사는 개발자가 화면의 가능한 모든 표시 변형을 처리하지 않은 상태를 방지합니다.

sealed class와 enum class 비교

enum class와 sealed class는 종종 혼동되지만, 서로 다른 목적과 기능을 가지고 있습니다.

특징sealed classenum class
인스턴스여러 개(data class), 하나(object)상수당 정확히 하나
속성각 하위 클래스마다 다름모든 상수에 동일
상속가능(sealed class에서)불가능(암시적 final)
생성자매개변수를 가질 수 있음모든 상수에 공통만 가능
계층 구조제한됨, sealed고정된 상수 집합

sealed class와 enum class 사이의 선택은 작업에 따라 다릅니다. 변형이 추가 데이터를 전달하지 않으면 enum을 사용하십시오. 각 변형에 고유한 필드가 포함되어 있으면 sealed class 또는 sealed interface를 사용하십시오.

실용적인 사용 시나리오

sealed 유형은 타입 안전 모델링이 필요한 일련의 표준 시나리오에서 Kotlin 프로젝트에 사용됩니다.

Jetpack Compose의 UI 상태

Compose 화면은 가능한 모든 상태(Idle, Loading, Content(data), Error(exception))를 설명하는 sealed class UiState를 가질 수 있습니다. when 표현식은 모든 상태가 처리되도록 보장합니다.

네트워크 요청 결과

NetworkResult(Success, Error, Loading 변형)는 Retrofit 및 Ktor를 사용하는 Kotlin 프로젝트의 표준 패턴입니다. sealed class는 각 요청 결과의 안전한 처리를 보장합니다.

멀티 모듈 프로젝트의 네비게이션

sealed interface를 사용한 네비게이션 경로는 모듈이 통합된 계층 구조 내에 있으면서 자체 경로를 선언할 수 있게 합니다. 이는 컴파일 타임에 알 수 없는 경로로 인한 오류를 제거합니다.

KotlinConf(2025)에 따르면, sealed class와 sealed interface는 현대 Kotlin 애플리케이션에서 타입 안전 디자인의 기초입니다. 이들은 data class와 결합되어 컴파일 타임 안전성을 잃지 않으면서 복잡한 도메인 구조를 모델링합니다.

자주 묻는 질문

sealed class의 하위 클래스는 어디에 선언해야 하나요?

sealed class의 모든 직접 하위 클래스는 동일한 파일에 선언되어야 합니다. sealed interface에도 동일한 규칙이 적용됩니다. 구현은 하나의 파일에 있어야 합니다.

sealed interface가 다른 파일에 구현을 가질 수 있나요?

아니요, 단일 파일 규칙은 sealed interface에도 적용됩니다. 모든 구현은 sealed interface가 선언된 파일에 있어야 합니다.

sealed class와 sealed interface의 차이점은 무엇인가요?

sealed interface는 상태나 생성자가 없으며 다중 구현을 허용합니다. sealed class는 생성자와 공유 상태를 가질 수 있지만, 클래스는 하나의 sealed class만 상속할 수 있습니다.

sealed 클래스는 when 표현식에서 어떻게 도움이 되나요?

컴파일러가 when의 완전성을 확인합니다. 모든 하위 클래스가 처리되지 않으면 코드가 컴파일되지 않습니다. 이는 런타임 오류를 제거하고 코드를 더 안전하게 만듭니다.

sealed class가 생성자를 가질 수 있나요?

네, sealed class는 생성자를 가질 수 있습니다(기본적으로 private). 모든 하위 클래스는 super()를 통해 이 생성자에 매개변수를 전달할 수 있습니다.

요약

  • sealed class — 컴파일 타임에 알려진 하위 클래스가 있는 제한된 계층 구조
  • sealed interface — 다중 구현을 지원하는 유연한 대안(Kotlin 1.5+)
  • when — 컴파일러 검사가 있는 완전한 처리, else 불필요
  • 하나의 파일 — 모든 하위 클래스와 구현은 sealed 유형과 같은 파일에 있어야 함
  • 모델링 — UI 상태, 네트워크 결과, 네비게이션, 이벤트 시스템
  • 안전성 — when 처리 없이 새 하위 클래스를 추가하면 컴파일 오류 발생
  • 선택 — 기본적으로 sealed interface 선호, 공유 상태가 필요할 때 sealed class

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기