Tour of Scala

パッケージオブジェクト

Language

パッケージオブジェクト

Scalaはパッケージ全体を通して共有される便利なコンテナとしてパッケージオブジェクトを提供します。

パッケージオブジェクトは、変数やメソッド定義だけでなく、任意の定義を含むことができます。 例えば、それらはパッケージ全体で使われる型エイリアスと暗黙の変換を保有するためによく使われます。 パッケージオブジェクトはScalaクラスやトレイトを継承することもできます。

慣習として、パッケージオブジェクトのソースコードは通常package.scalaという名のソースファイルに設置されます。

1つのパッケージはパッケージオブジェクトを1つ持てます。パッケージオブジェクト内の全ての定義はパッケージ自体のメンバーと見なされます。

以下の例を見てみましょう。まず1つのクラスFruitと3つのFruitオブジェクトがパッケージgardening.fruitsにあるとします。

// ファイル gardening/fruits/Fruit.scala の中
package gardening.fruits

case class Fruit(name: String, color: String)
object Apple extends Fruit("Apple", "green")
object Plum extends Fruit("Plum", "blue")
object Banana extends Fruit("Banana", "yellow")

ここで、変数plantedとメソッドshowFruitを直接パッケージgardening.fruits内に置きたいとします。 こちらがその方法になります。

// ファイル gardening/fruits/package.scala の中
package gardening
package object fruits {
  val planted = List(Apple, Plum, Banana)
  def showFruit(fruit: Fruit): Unit = {
    println(s"${fruit.name}s are ${fruit.color}")
  }
}

利用側がどのようになるかの例としては、以下のオブジェクトPrintPlantedは、ワイルドカードインポートでクラスFruitと全く同様にplantedshowFruitをインポートしています。

// ファイル PrintPlanted.scala の中
import gardening.fruits._
object PrintPlanted {
  def main(args: Array[String]): Unit = {
    for (fruit <- fruits.planted) {
      showFruit(fruit)
    }
  }
}

パッケージオブジェクトは他のオブジェクトのように、継承を利用して構成できます。例えば、一つのパッケージオブジェクトが2つのトレイトをミックスインしている例を示します。

package object fruits extends FruitAliases with FruitHelpers {
  // ヘルパーと変数がここに続きます。
}

メソッドオーバーライドはパッケージオブジェクト内では動作しないので気をつけましょう。

Contributors to this page: