パッケージオブジェクト
パッケージオブジェクトの簡単な利用方法
パッケージオブジェクトが無い場合(2.7まで)
すべてをクラス(オブジェクト)の中で定義するしかない。
package foo
object Foo {
type MOJI = String
val SomeString = "hello world"
}
....
....
import foo.Foo._
object Sample {
def main(args: Array[String]) {
val a:MOJI = "Greeting:"
println(a + SomeString)
}
}上例では、例えばStringのエイリアスとしてMOJIを使いたいのだが、それはFooというオブジェクトの中に定義し、それを「import foo.Foo._」としてから使うしかない。
パッケージオブジェクトのある場合(2.8以降)
あたかもパッケージに直接記述できるかのようになる。
package object foo {
type MOJI = String
val SomeString = "hello world"
}
...
...
import foo._
object Sample {
def main(args: Array[String]) {
val a:MOJI = "Greeting:"
println(a + SomeString)
}
}importする場合は、もはやクラス(オブジェクト)を指定する必要はなく、「import foo._」でよい。 もちろん、typeやvalだけでなく、defも書ける(はず)。
何の役に立つのか?
- 上例からも明らかなように、クラスを指定しなくともその機能が使用できる。ここにはパッケージ全体で共通の定義等を置いておくことができる。でもこれだけでは「素晴らしく便利」とは言えない。
- 例えば、クラスのパッケージを移動したいが後方互換性を残しておきたい場合。
例えば、パッケージfooにBarというクラスがあったとする。
package foo
class Bar {
}これを、some.whereというパッケージに移動したいのだが、単純に移動すると、foo.Barを使用中のユーザは困ってしまう。 そこで、Barをsome.whereに移すと同時に、パッケージオブジェクトfooとして次のような定義を行う。
package object foo {
type Bar = some.where.Bar
}こうして、後方互換性が保たれるという仕組み。
パッケージオブジェクトは「オブジェクト」
パッケージオブジェクトは「オブジェクト」なので、普通のオブジェクトと同様に継承等ができてしまう。
package foo {
class Class {
type NUMBER = Int
}
}
package object foo extends Class {
type MOJI = String
val SomeString = "hello world"
}
....
import foo._
object Sample {
def main(args: Array[String]) {
val a:MOJI = "Greeting:"
val n:NUMBER = 1
println(a + SomeString + n)
}
}