만약 하위 클래스에서 부모 클래스의 props를 사용하지 않고 항상 오버라이드하여 자신의 상태만을 비교한다면, Equatable을 직접 상속하는 것과 큰 차이가 없습니다.
기본 예시 코드~
abstract class SleepTimeState extends Equatable {
const SleepTimeState();
@override
List<Object> get props => [];
}
final class SleepTimeCalcFailure extends SleepTimeState {
const SleepTimeCalcFailure(this.ex);
final Exception ex;
@override
List<Object> get props => [ex];
}
자신의 상태만 비교한다면, 직접 상속과 차이가 없어요. 이렇게 사용해도 무방해요.
final class SleepTimeCalcFailure extends Equatable {
const SleepTimeCalcFailure(this.ex);
final Exception ex;
@override
List<Object> get props => [ex];
}
이 코드가 extends SleepTimeState를 사용하는 것과 동일한 효과를 냅니다. SleepTimeState 자체에서 특별한 로직이나 상태 관리가 없다면, 상속 구조는 불필요하게 복잡해질 수 있습니다.
상속 구조가 유효할 때
상속을 사용하는 주요 이유는 공통 로직을 재사용하거나, 부모 클래스로 묶어 다형성을 활용하는 것입니다. 예를 들어, SleepTimeState가 여러 종류의 상태(성공, 실패, 진행 중 등)를 포함하는 경우에 유용할 수 있습니다.
만약 SleepTimeState가 다른 상태도 포함하고 있고, props에 공통 속성이나 로직이 들어가야 한다면 상속을 사용하는 것이 좋습니다. 예를 들어~
abstract class SleepTimeState extends Equatable {
const SleepTimeState();
final DateTime timestamp = DateTime.now(); // 공통 속성
@override
List<Object> get props => [timestamp]; // 공통적으로 비교할 속성
}
final class SleepTimeCalcFailure extends SleepTimeState {
const SleepTimeCalcFailure(this.ex);
final Exception ex;
@override
List<Object> get props => super.props + [ex]; // 부모의 props에 덧붙이기
}
이 경우, SleepTimeState에서 공통적으로 비교할 값이 존재하고, 하위 클래스가 그 위에 추가적인 값을 덧붙여서 비교하게 되므로 상속이 의미가 있습니다.
결론
- 단순히
props를 오버라이드하기만 하는 경우라면, 상속보다는Equatable을 직접 상속하는 것이 더 간결합니다. - 상속 구조가 유효한 경우는 부모 클래스에서 공통 로직이나 상태를 제공할 때입니다.
