Enum 클래스의 확장판이라고 생각하면 쉽다.
가장 큰 차이점은 Enum은 하나의 인스턴스만 사용할 수 있고 생성자도 동일하지만
Sealed Class는 state(상태값)을 포함한 여러 인스턴스를 가질 수 있고 생성자도 다르게 가질 수 있다.
Pattern matching구조(Switch, if-else)에서
새로운 타입이 추가됐을때 혹은 타입이 누락됐을때 컴파일러에서 자식 클래스(지정해준 타입들)을 알고있어서 에러 가능성을 확 잡아줄 수 있다!
Sealed Class는 state(상태값)을 포함한 여러 인스턴스를 가질 수 있고 생성자도 다르게 가질 수 있다.
앱을 만들때 여러 뷰타입을 지정해놓고 컴포넌트를 만드는 경우가 있다.
각 뷰타입마다 파라미터가 달라질 수 있는데 Enum의 경우 불가하지만
sealed 클래스를 쓰면 아래 예시처럼 가능하다.
또한, 뷰타입이 많아졌을때 pattern matching구조에서 누락된 뷰타입이나 잘못된 뷰타입을 잡아줄 수 있다.
enum class ViewType
{
PRD1,
PRD2(val prdid), // Enum은 생성자가 동일. 이런 형태는 불가함.
}
sealed class ViewType
{
data class PRD1(val prdId: Int)
data class PRD2(val prdNm: String)
}
[패키지]
https://pub.dev/packages/sealed_unions
[참고]
https://resocoder.com/2019/09/16/sealed-unions-in-dart-never-write-an-if-statement-again-kind-of/
[요약]
WeatherInitial,
WeatherLoading,
WeatherLoaded,
세가지 상태에 대해 Sealed Class사용여부에 따른 차이점을 보면
String widgetBuilder(WeatherState state) {
if (state is WeatherInitial) {
return "Some initial widget";
} else if (state is WeatherLoading) {
return "Circular progress indicator";
} else if (state is WeatherLoaded) {
return "The temperature is ${state.temperature}";
}
}
class WeatherState
extends Union3Impl<_WeatherInitial, _WeatherLoading, _WeatherLoaded> {
static final Triplet<_WeatherInitial, _WeatherLoading, _WeatherLoaded>
_factory =
const Triplet<_WeatherInitial, _WeatherLoading, _WeatherLoaded>();
states
WeatherState._(
Union3<_WeatherInitial, _WeatherLoading, _WeatherLoaded> union,
) : super(union);
classes
factory WeatherState.initial() =>
WeatherState._(_factory.first(_WeatherInitial()));
factory WeatherState.loading() =>
WeatherState._(_factory.second(_WeatherLoading()));
factory WeatherState.loaded(int temperature) =>
WeatherState._(_factory.third(_WeatherLoaded(temperature)));
}
class _WeatherInitial {}
class _WeatherLoading {}
class _WeatherLoaded {
final int temperature;
_WeatherLoaded(this.temperature);
}
String widgetBuilder(WeatherState state) {
return state.join(
(initial) => "Some initial widget",
(loading) => "Circular progress indicator",
(loaded) => "The temperature is ${loaded.temperature}",
);
}