Scala

sealed 키워드와 final 키워드의 차이

partner_jun 2017. 6. 13. 15:14

두 가지 키워드 모두 자바에서 클래스에 쓰는 final 키워드와 마찬가지로 더 이상 상속하지 못하게 할 때 사용한다. 하지만 sealed 키워드는 final 키워드와 달리 같은 파일에서는 상속할 수 있다. 하나의 파일에 하나의 구현(Nested Class를 제외하고)만 가능한 자바와 달리 스칼라는 그런 제한이 없기 때문에 존재하는 키워드라고 볼 수 있다.


sealed class Fruit(color: String) {
def printColor = println(color)
}

class Apple extends Fruit("Red") {
def print = "Apple"
}

같은 파일에서의 sealed class 상속


class Banana extends Fruit("Yellow") {

}

다른 파일에서 sealed class를 상속했을 때는 위와 같은 에러 메시지가 출력된다.



StackOverFlow의 답을 보면 sealed 키워드 사용의 예로 Option의 구현을 들고 있다.

sealed abstract class Option[+A] extends Product with Serializable {

Option의 선언부


final case class Some[+A](x: A) extends Option[A] {
def isEmpty = false
def get = x
}
case object None extends Option[Nothing] {
def isEmpty = true
def get = throw new NoSuchElementException("None.get")
}

Some과 None의 선언부. 

세 가지 클래스가 모두 같은 파일에 구현되어 있기 때문에 상속 할 수 있다.



재미있는 점은 sealed 키워드는 class뿐 아니라 trait에도 사용이 가능하다는 것이다.

sealed trait ColorPrintable {
val color: String
def printColor = println(color)
}

class Apple extends ColorPrintable {
override val color: String = "Red"
}

같은 파일에 구현된 sealed trait과 클래스


class Banana extends ColorPrintable {
override val color: String = "Yellow"
}

다른 파일에서 상속하면 역시 같은 에러가 발생한다.


  

trait에 접근제한자(혹은 패키지 제한)를 사용하면 해당 trait에의 접근 자체가 불가능해져 버리기 때문에 trait상속 제한만이 필요하다면 sealed 키워드 사용을 고려해 볼 필요가 있다.