みなさんは、enumを使ってますか?
そうですよね。enum使いますよね。
でも、少し変なとこないですか?
とりあえずソースを見てみよう
ソースを書くのが面倒だったんで、昔に書いたソースが良さそうだったんで、このソース(抜粋)でいきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | enum Scale { //括弧内は、音階の周波数、ふつーのドレミ A4(440.0,"ラ4"), B4(493.9,"シ4"), C5(523.3,"ド5"), D5(587.3,"レ5"), E5(659.3,"ミ5"), F5(698.5,"ファ5"), G5(784.0,"ソ5"), A5(880.0,"ラ5"); //括弧内のデータ型を宣言 private final double frequency; private final String scaleName; //コンストラクタ Scale(double frequency, String scaleName) { this.frequency = frequency; this.scaleName = scaleName; } //アクセサ public double frequency() { return frequency; } public String scaleName() { return scaleName; } } |
何もおかしくないけど?
はい。おかしくないです。ふつーのenumです。
値を持たせようと思ったら、こんな感じに書くと思います。
・・・。
茶番は終わりにして・・・
タイトルに書いてしまいましたが、コンストラクタ。変ですよね?
enumはクラス。列挙子にはそのクラスのインスタンス。
enumはクラスです。
このあたりは、近いうちに?Youtubeでやる?と思うので?、ここでは割愛します。
んで、その作成したenumは、java.lang.Enumクラスを継承したクラスです。
enumの列挙子には、原則、そのクラスのインスタンスが格納されるんですが、このときには何らかの方法でインスタンス化が必要です。
java.lang.Enumのコンストラクタを見てみよう
インスタンス化したいので、親であるjava.lang.Enumのコンストラクタは、superしないといけません。
java.lang.Enumのコンストラクタは、これだけ。漢気にあふれてます。
1 | protected Enum(String name, int ordinal) |
ちなみに、さっきのコードのコンストラクタは、これでした。。
1 | Scale(double frequency, String scaleName) |
違和感ないですか?
ん?呼べないじゃん!
はい。このままではsuperできませんね。
enumをこのままクラスに書き直してもコンパイルエラーってことですね。
どゆこと?
これは、javaのコンパイラがいい仕事をすることで、解決します。
つまり、ソースコードを自動的に改変改良したうえで、コンパイルする。ってことです。
さっきのコードでいくと、具体的には、こんな感じになります。
1 2 3 4 5 | Scale(String name, int ordinal, double frequency, String scaleName) { super(name , ordinal); this.frequency = frequency; this.scaleName = scaleName; } |
第1引数、第2引数は、java.lang.Enumのコンストラクタの定義。
第3引数以降が、さっきのコードのコンストラクタです。
といった感じで、コンパイラが書換えて、第1引数、第2引数を足してくれます。
また、列挙子はフィールド変数(定数)になるので、そのクラスのインスタンス化、staticメソッドのコードなどを追加してくれます。
これで、無事コンパイルできますね。めでたし。
ということで、今回はenumのコンストラクタで見てきましたが、enumがクラスに変換されることを考えれば、ふだんenumで書いているコードの記述は不完全ってことです。
ふだん書いているenumのコードは、見かけ上、辻褄が合っているように見えるだけで、クラスになると少し中身は変わるっていうお話しでした。
でも、この仕組みのおかげで、簡単に書くことができるんですよね。助かります。
Youtubeの方で、たぶんenumをやるつもり?なんですが、しばらくはここまでやらないかなー。
と思ったんで、とりあえずこっちに書いてみた次第です。