= パッケージオブジェクト = == パッケージオブジェクトの簡単な利用方法 == === パッケージオブジェクトが無い場合(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) } } }}}