Tour of Scala

複合型

Language

ときどき、あるオブジェクトの型が、複数の他の型のサブタイプであると表現する必要が生じます。 Scalaでは、これは複合型を用いて表現できます。複合型とはオブジェクトの型同士を重ねることです。

2つのトレイト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の型は何かという疑問が生じます。もしCloneableであれば、オブジェクトをcloneすることができますが、resetすることはできません。もしResetableであれば、resetすることができますが、cloneの操作はできません。そのような状態で型キャストを回避するためにobjの型をCloneableResetableの両方であると指定することができます。Scalaではこの複合型はCloneable with Resetableのように書くことができます。

こちらが書き変えた関数です。

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

複合型は複数のオブジェクトの型からなり、一つだけの細別型(refinement)を持てます。細別型は既存オブジェクトのメンバーのシグネチャを絞り込むのに使えます。 一般的な形はA with B with C ... { refinement }です。

細別の使い方の例はミックスインを用いたクラス合成のページにあります。

Contributors to this page: