티스토리 뷰

Kotlin

[Kotlin] Sealed class

parkho79 2026. 5. 7. 19:20
728x90

Android app 을 개발하다 보면 네트워크 통신 결과나 배송 시스템처럼 '현재 진행 상황'에 따라 각기 다른 데이터를 보여줘야 하는 상태(State) 관리 로직을 자주 마주하게 된다. 이때 어떤 설계 방식을 선택하느냐에 따라 코드의 가독성과 안정성, 즉 코드의 품질이 결정된다.

 

그동안 우리는 관습적으로 interface나 enum을 사용해 왔다. 하지만 실무에서 마주하는 복잡한 상태들을 담아내기에 interface는 너무 '자유분방'해서 통제가 안 되고, enum은 너무 '경직'되어 있어 유연함이 떨어지는 탓에 종종 예외 상황이 터지곤 한다.

 

이번 포스팅에서는 코틀린에서 상태 관리를 유연하게 만들어주는 Sealed Class에 대해 알아보자.



상태 관리, 무엇이 다를까?

배송 시스템을 예로 들어 세 가지 방식의 차이점을 알아보자.

 

◼ interface / abstract (공용 게시판)

"배송 상태"라고 써진 종이만 있으면 누구나 글을 쓸 수 있는 자유 게시판과 같다.

배송 업체와 상관없는 사람이 갑자기 '외계인이 가져감' 같은 상태를 써 붙여도 시스템이 막지 못한다.

 

◼ enum (기성품 도장)

모든 도장에 "기사 이름", "현재 위치" 칸이 미리 파져 있는 고정된 도장 세트와 같다.

아직 기사가 배정 안 된 '상품 준비 중' 상태인데도 기사 이름을 공란으로라도 찍어야 하는 비효율이 생긴다.

 

◼ Sealed Class (공식 한정판 앱)

본사가 딱 지정한 단계(준비, 배송, 완료)만 존재한다.

특히 '준비 중'엔 데이터가 없고, '배송 중'엔 기사 정보가 있으며, '완료'엔 도착 시간이 담기는 등 단계별로 최적화된 정보를 담을 수 있다.



728x90



상태 관리 예제

위에서 얘기한 배송 시스템 예제를 코드를 통해 자세히 알아보자.

 

◼ interface / abstract 방식 (통제 불가능한 확장)

프로젝트 어디서든 상속이 가능해서, 내가 예상치 못한 상태가 튀어나와 앱이 죽을 수 있다.

 

◼ enum 방식 (불필요한 데이터 강제)

모든 상태가 같은 생성자 구조를 가져야 해서, 배송 기사가 없는 상태에서도 기사 이름을 강제로 넣어야 한다.

 

◼ Sealed Class 방식 (완벽한 상태 설계)

각 상태에 꼭 필요한 데이터만 정의하고, 외부의 침입을 막을 수 있다.



Sealed Class 상속받기

상속받는 형태에 따라 내부 동작이 조금 달라지니 이 점을 꼭 기억하자.

◼ class(또는 data class)로 상속

데이터를 포함해야 할 때 쓴다. 일반 class로 상속받으면 인스턴스끼리 값이 같은지 비교할 때 equals를 직접 오버라이드해야 경고가 안 난다.

(보통 data class를 써서 이 문제를 해결한다.)

 

◼ object로 상속

'준비 중'처럼 데이터는 없고 상태만 나타낼 때 쓴다.

싱글톤이라 equals 구현 없이도 메모리를 아끼며 안전하게 비교할 수 있다.



주의사항

◼ 같은 패키지의 자식 클래스만 상속 가능

Sealed Class는 자신의 하위 클래스를 동일한 패키지 내로 제한한다.

외부 모듈에서 내 배송 시스템에 '갑자기 튀어나온 상태'를 끼워 넣을 수 없게 만드는 철저한 보호막이다.

 

◼ 추상 클래스로 직접 인스턴스 생성 불가능

Sealed Class는 규격일 뿐이다.

반드시 구체적인 자식(Preparing, Shipping 등)을 통해서만 실체화할 수 있어 코드가 명확해진다.

// Error! 배송 상태라는 개념 자체를 객체로 만들 수 없다.
val status = DeliveryStatus()



728x90

'Kotlin' 카테고리의 다른 글

[Kotlin] @JvmOverloads 이용하기  (0) 2026.04.10
댓글