Kotlin/Kotlin | Spring 학습기록

[Kotlin] Sealed Class를 이용한 무분별한 상속 확장을 방지하기

kth990303 2022. 6. 4. 20:56
반응형

kotlin의 클래스와 메서드는 기본적으로 final이다. 따라서 어떠한 클래스의 상속을 허용하려면 클래스 앞에 open 변경자를 붙여주어야 한다. 상속을 사용하고 싶어서 open 변경자로 클래스를 열어주었는데, 외부에서 무분별하게 상속을 통해 기능을 확장시키는 건 막고 싶을 수 있다. 이러한 경우 Sealed Class를 이용하면 좋다.


Sealed Class

Operator 인터페이스의 구현체들인 Plus, Minus, Multi 클래스들이 있다.

calc 함수는 when절을 이용하여 Plus, Minus, Multi인지 확인하고 결과를 반환하는 함수이다. 만약, 어떤 것에도 해당하지 않으면 else문을 작성해주어야 한다. else문이 없으면 위와 같이 컴파일 에러가 발생한다.

 

외부에서 Operator의 구현체를 임의로 추가적으로 작성하여 원치 않는 설계가 발생할 수 있음을 걱정하여 확장을 막고 싶다고 하자. 이 때, Sealed class를 사용하면 된다.

when 절을 사용했을 때, else문이 존재하지 않아도 컴파일 에러가 발생하지 않는다. Operator를 sealed class로 생성해두었기 때문이다. 이 경우에, 나중에 sealed 클래스의 상속 계층에 새 하위 클래스를 추가하면 컴파일 에러를 발생시킨다. 이렇게 sealed 클래스는 무분별한 확장을 막아둘 수 있다.


Enum VS Sealed Class

Enum 또한 하위 클래스의 타입이 제한돼있다는 점에서 Sealed class와 비슷하다고 생각될 수 있다. 그럼 enum과 sealed class의 차이는 무엇일까? 아래의 차이점들이 존재한다.

  • Enum은 Single Instance로 하나의 객체만 생성 가능하지만, Sealed Class는 여러 개의 객체를 생성할 수 있다.

위 클래스는 enum 클래스에서의 PLUS, MINUS, MULTI 상수들이다.

상수라는 뜻에서 알 수 있듯이, 굉장히 정적이며 하나의 값(single instance)를 가진다. 이는 인스턴스 객체들을 가지는 Sealed Class와 엄연히 큰 차이를 가진다.

 

(추가로, JAVA 개발자라면 위 코드에서 문자열 비교 ==를 보고 의문을 가질 수 있다. 코틀린은 JAVA와 다르게 문자열에서 == 를 사용할 수 있다. JAVA에서 발생했던 문자열 동등성 이슈를 겪지 않는다.)

 

  • Enum의 상수들은 생성자 꼴이 동일해야 하나, Sealed Class의 클래스들은 생성자 꼴에 제한이 없다.

Plus, Minus의 생성자 꼴이 다름을 확인할 수 있다.


참고한 글은 아래와 같다.

 

반응형