Scalaが難しいので初歩の初歩からやり直すことにした(その2)
object HelloWorld { def main(args: Array[String]): Unit = { System.out.println("Hello, Scala!") } }
一行目
object HelloWorld {
- 「object」ってなんだ?! 「class」じゃないのか?!
object [オブジェクト名] って書くと、まずシングルトンなクラスを定義してくれて、おまけにインスタンスの生成までやってくれる。
[オブジェクト名]はオブジェクトのように扱うことができる。スゴイ。オブジェクトそのものなんだから『オブジェクトのように』っていう表現はおかしいな。変数のように扱うことができる。
不変オブジェクト(『定数』と呼ぶべきか)になって再代入はできない。
でも再定義はできる。再定義を禁止する方法はないのかな?
- 「public」はいらないのか?!
オブジェクト定義の頭に「public」ってつけると怒られる。「protected」と「private」は怒られない。Javaのクラス定義とは真逆。
「protected」ってつけても、「private」ってつけても、あるいは何もつけなくても、他のところから普通に見えてしまう。これは面妖な。
色々やってみた結果
オブジェクト定義(クラス定義ではない)
scala> object obj { | var id = 0 | var name = "no name" | def sayName = { | System.out.println( "My name is " + name ); | } | } defined module obj
モジュール?
変数と同じように扱える
scala> System.out.println( obj ) line1$object$$iw$$iw$obj$@1a40fff scala> System.out.println( obj.getClass ) class line1$object$$iw$$iw$obj$ scala> System.out.println( obj.toString ) line1$object$$iw$$iw$obj$@1a40fff scala> System.out.println( obj.id ) 0 scala> System.out.println( obj.name ) no name scala> obj.sayName My name is no name
プロパティに値を設定できる
scala> obj.id = 1 scala> obj.name = "syttru" scala> System.out.println( obj.id ) 1 scala> System.out.println( obj.name ) syttru scala> obj.sayName My name is syttru
シングルトンかつ不変
scala> obj = 1 <console>:7: error: assignment to immutable value ( 不変の値に代入するんじゃない! ) obj = 1 ^
他の変数に代入することはできる
scala> var a = obj a: object obj = obj$@1a40fff scala> a.sayName My name is syttru
再定義されたら変わっちゃう
scala> var obj = 1 obj: Int = 1 scala> System.out.println( obj ) 1
「public」とか「protected」とか「private」とかつけてみた
scala> public object publicObj error: That kind of statement combination is not supported by the interpreter. ( その種類の文の組み合わせはインタプリタによってサポートされません。 ) scala> protected object protectedObj defined module protectedObj scala> private object privateObj defined module privateObj
インタープリターだからダメなのかな
じゃあコンパイルしてみよう
// public_object.scala // publicなオブジェクト public object publicObj
// protected_object.scala // protected なオブジェクト protected object protectedObj
// nomodifier_object.scala // 無印なオブジェクト object nomodifierObj
// private_object.scala // private なオブジェクト private object privateObj
のーみそこねこねコンパイル
$ scalac public_object.scala public_object.scala:4: error: expected class or object definition ( 予想されたクラスかオブジェクト定義 ) ??? わからん! 英語キライ public object publicObj ^ one error found $ scalac protected_object.scala $ scalac nomodifier_object.scala $ scalac private_object.scala
やっぱり「public」だけが怒られる。出てくるエラーメッセージも、エキサイト翻訳だけが頼りの私には難しすぎる。
そもそもこれらはホントにスコープ修飾子なのか?
他のオブジェクトから参照してみよう。
// main.scala object main { def main(args: Array[String]) { System.out.println( privateObj ) System.out.println( protectedObj ) System.out.println( nomodifierObj ) } }
$ scalac main.scala $ scala main privateObj$@5e0602 protectedObj$@1621e42 nomodifierObj$@1787038
全て正常にコンパイルして実行できた。うーむ。謎だ。