Tour of Scala

합성 타입

Language

때론 객체의 타입을 여러 다른 타입의 서브타입으로 표현해야 할 때가 있다. 스칼라에선 합성 타입(Compound Types)으로 표현될 수 있는데, 이는 객체 타입들의 교차점을 의미한다.

CloneableResetable이라는 두 트레잇을 생각해보자:

trait Cloneable extends java.lang.Cloneable {
  override def clone(): Cloneable = { 
    super.clone().asInstanceOf[Cloneable]
  }
}
trait Resetable {
  def reset: Unit
}

그리고 어떤 객체를 파라미터로 받아 복제한 뒤 원래의 객체를 초기화하는 cloneAndReset 이라는 함수를 작성하려고 한다:

def cloneAndReset(obj: ?): Cloneable = {
  val cloned = obj.clone()
  obj.reset
  cloned
}

여기에서 파라미터 obj의 타입이 무엇인가 하는 의문을 가질 수 있다. 만약 타입이 Clonable이라면 이 객체는 복제될(Cloned) 수 있지만 리셋될(reset) 수는 없다. 반면 타입이 Resetable이라면 이 객체를 리셋할(reset) 수는 있지만 clone 기능을 사용할 수는 없다. 이러한 상황에서 타입 캐스팅을 피하기 위해 두개의 타입 ClonableResetable 모두를 지정해 줄 수 있다. 스칼라의 이러한 합성타입은 다음과 같이 쓰인다. : Clonable with Resetable

위의 함수를 다시 작성하면 다음과 같다.

def cloneAndReset(obj: Cloneable with Resetable): Cloneable = {
  //...
}

합성 타입은 여러 객체 타입으로 구성될 수 있고, 단일 리파인먼트를 가짐으로써 객체 멤버의 시그니처의 범위를 좁힐 수도 있다. 일반적인 형태는 A with B with C ... { 리파인먼트 }이다.

리파인먼트 사용 예제는 추상 타입 에 있다.

윤창석, 이한욱 옮김, 고광현 수정