Javaみたく明示的にアクセスメソッドを定義する必要はないようです。素敵ですね。
パターン1:publicなvarフィールドを定義した場合
このように、publicなvarフィールドを定義するとコンパイル時に自動的にアクセスメソッドを出力してくれます。class Hoge { var hoge1: String = _ var hoge2: Int = _ }自動で生成されたアクセスメソッドを呼び出すには、フィールドに直接アクセスするようにしてあげればよいです。
val hoge = new Hoge hoge.hoge1 = "hoge" // hoge1に値を設定 hoge.hoge2 = 1 // hoge2に値を設定 println(hoge.hoge1) // hoge1の値を取得 println(hoge.hoge2) // hoge2の値を取得
コンパイル後に出力されたクラスファイルをjadって見てみると、こんなルールになっているのがわかる。
- varなフィールドはprivateになっている。
- setterは、プロパティ名 + "_="になっている。
=は、コンパイル時にJavaで認識できる文字に置き換えられるので「$eq」となっている。 - getterは、プロパティ名になっている。
//*********************************************** // Hogeクラス //*********************************************** public class Hoge implements ScalaObject { // hoge1のgetter public String hoge1() { return hoge1; } // hoge1のsetter public void hoge1_$eq(String s) { hoge1 = s; } // hoge2のgetter public int hoge2() { return hoge2; } // hoge2のsetter public void hoge2_$eq(int i) { hoge2 = i; } public Hoge() { } // 公開フィールドは、privateなフィールドとなっている。 private String hoge1; private int hoge2; } //*********************************************** // アクセスメソッドを呼び出すコード //*********************************************** Hoge hoge = new Hoge(); // setter(プロパティ名 + "_=")を呼び出すコードに変換されているのがわかる。 hoge.hoge1_$eq("hoge"); hoge.hoge2_$eq(1); Predef$.MODULE$.println(hoge.hoge1()); Predef$.MODULE$.println(BoxesRunTime.boxToInteger(hoge.hoge2()));ちなみち、varフィールドをprivateにするとアクセスメソッドが生成されないのでこんな感じにコンパイルエラーが出る。
Error:Error:line (6)error: variable hoge1 in class Hoge cannot be accessed in Hoge hoge.hoge1 = "hoge" Error:Error:line (7)error: variable hoge2 in class Hoge cannot be accessed in Hoge hoge.hoge2 = 1 Error:Error:line (9)error: variable hoge1 in class Hoge cannot be accessed in Hoge println(hoge.hoge1) Error:Error:line (10)error: variable hoge2 in class Hoge cannot be accessed in Hoge println(hoge.hoge2)
パターン2:明示的にアクセスメソッドを定義する方法
明示的にアクセスメソッドを定義するには、フィールドをprivateにしてあげてパターン1で自動生成された形式でsetterとgetterを宣言してあげればよいです。例えば、アクセスメソッドで処理をしたい場合やgetterのみを宣言する場合に使います。(Javaのように、getHogeやsetHogeを宣言する必要はないです。)
気をつけないといけないのは、フィールド名とgetter名が同じになってはいけないのと、
setter名は、プロパティ名の後に「_=」をつけるのを忘れないこと。「_」と「=」の間にスペース入れちゃうのもダメ。
// フィールドはprivateで宣言する。 private var h1: String = _ private var h2: Int = _ // getter def hoge1: String = h1 // setter def hoge2_=(hoge2: Int) { require(hoge2 > 100) h2 = hoge2; } // getter def hoge2: Int = h2