第51回 クラスを使って「定数」や「定番の処理」を管理してみよう
クラスの仕組みを利用すると,一目で何に使うのかわかりにくいような値や,将来的に変更があるかもしれないような値を,見た目にわかりやすい定数として管理することができます。また,よく使う定番の処理を「クラス・メソッド」として扱うこともできます。
「何かをひとまとめにする」ためにクラスを使う今までご紹介した記事では,カスタム・クラスを使用する際には,new演算子を使用してインスタンスを生成し,それを利用してきました。インスタンスを生成するということは「メモリー上で,インスタンス変数を書き込む場所を確保する」ことでしたね。カスタム・クラスには,上記の方法とは別に,new演算子でインスタンスを作成しなくても使用することのできる「クラス・プロパティ」「クラス・メソッド」という仕組みが用意されています。この仕組みを使うと,すっきりと情報をまとめることができます(図1)。
図1: クラス・プロパティのイメージ(クリックするとムービーを表示します) クラスを使って,「わかりにくくて散らかりやすいもの」を「わかりやすく整理する」わけですね(*1)。
西暦を和暦に変換するクラスを作成してみよう日本に住んでいる皆さんは,「2007年」のような西暦を「明治・大正・昭和・平成○○年」といった和暦に変換する機会があるかと思います。西暦から和暦を求めるには,表1のような数値を西暦の数値から減算すればOKです。
例えば,「2007年」を「平成」に変換するならば,「2007」から「1988」を引いて「19」。「平成19年」となるわけです。でも,この計算,咄嗟にできますか? 急に言われると,なかなか数字がでてこないですよね。 さらには元号が切り替わる年や日付なども考え出すと,もうお手上げです(表2)(*2)。
こういう計算は西暦と和暦を変換するプログラムを作ってしまい,そこに任せるのが後々楽になりそうですね。いろいろなコードの書き方があるかとは思いますが,筆者は次のようにコードを記述してみました。
//元号を表す文字列を配列で管理する var gengouString:Array = ["明治","大正","昭和","平成"]; //元号の計算に使用する数値を配列で管理する var gengouNumber:Array = [1867,1911,1925,1988]; //どの元号なのかは,数値で管理するルールとする。 //0:明治 1:大正 2:昭和 3:平成 基本的な方針は,四つの元号に対する元号名と,計算の際に使う数値を配列に入れて管理し,どの元号の計算を行うか,などの判断は,配列のインデックス番号で管理するというものです。こうしておけば「明治」で計算をしたい場合には,インデックス番号「0」の配列の値を取り出すと,それぞれ「明治」「1867」と必要な文字列と数値が取り出せます。 さらに,この配列とインデックス番号のルールを使って,西暦から指定した元号での和暦の文字列を求める関数「convert」を追加します。
//一つ目の引数として受け取った日付を,
//二つ目の引数で指定した和暦として返す関数
function convert(_day:Date,_index:Number){
//2番目の引数の値に応じた文字列や数値を配列から取り出して計算
var _g:String = gengouString[_index] +
String(_day.getFullYear()-gengouNumber[_index]) + "年";
var _m:String = String(_day.getMonth() + 1) + "月";
var _d:String = String(_day.getDate()) + "日";
return _g + _m + _d;
}
この関数を使って「2007年7月13日」を「平成」形式で変換した結果を表示してみましょう。
//「2007年7月13日」を「平成」形式で変換
trace("変換結果は、" + convert(new Date(2007,6,13),3));
Dateクラスを使用して任意の日付情報を作成する際には,「new Date(年,月,日)」とコードを記述します。この際,「月」の情報は,「1月」を「0」として指定しますのでご注意を。今回の用に「7月」を指定したい場合には,「6」と,実際の月の数字よりも一つ減算した値を指定してあげればOKというわけですね。 さて,このコードの実行結果はというと,図2のようになります。きちんと和暦に変換されていますね。
図2: 西暦が和暦に変換された さて,基本的な変換ができることが確認できましたので,この処理を使いまわせるようにクラス化してみたいと思います。クラス名は,そうですね,そのまんま「Wareki」としてみます(図3)。
図3: 和暦への変換処理を管理する「Wareki」クラスを作成する 先ほどの処理をまとめると,Warekiクラスのコードは次のようになります。
//和暦に関する情報をまとめたクラス
class Wareki {
//一つ目の引数の日付を,二つ目の引数の値に応じた元号で変換する関数
function convert(_day:Date,_index:Number):String{
//元号を表す文字列を配列で管理する
var gengouString:Array = ["明治","大正","昭和","平成"];
//元号の計算に使用する数値を配列で管理する
var gengouNumber:Array = [1867,1911,1925,1988];
//どの元号なのかは,数値で管理するルールとする。
//0:明治 1:大正 2:昭和 3:平成
//2番目の引数の値に応じた文字列や数値を配列から取り出して計算
var _g:String = gengouString[_index] +
String(_day.getFullYear()-gengouNumber[_index]) + "年";
var _m:String = String(_day.getMonth() + 1) + "月";
var _d:String = String(_day.getDate()) + "日";
return _g + _m + _d;
}
}
Warekiクラスを,「convertメソッド」のみを持つクラスとして定義できました。でもちょっと待ってください。このままでは,Warekiクラスのconvertメソッドを利用するには,以下のようにnew演算子を使ってインスタンスを生成しなくてはいけません。
//convertメソッドを使用したいので,Warekiクラスのインスタンスを生成
var _w:Wareki = new Wareki();
//2007年7月13日を「平成」形式で変換
var _day:Date = new Date(2007,6,13);
trace("変換結果は," + _w.convert(_day,3));
単に変換したいだけなのに,なんだかひと手間多い様な気がしますよね。そういえば,計算をするMathクラス等のメソッドは,「Math.random()」や「Math.floor()」のように,いちいちnew演算子でインスタンスを生成しなくても使えます。Warekiクラスでも,インスタンスを生成せずにconvertメソッドを使用したいものです。 このようなケースでは,「staticステートメント」を使用するのが効果的です。使用方法は簡単。インスタンスを生成しなくても使用したいメソッド名の先頭に「static」と付け加えるだけです(図4)。
図4: staticステートメントを付け加える staticステートメントを使って宣言されたメソッドは,「クラス・メソッド」もしくは,「静的メソッド」と呼ばれるメソッドとして認識されるようになります。クラス・メソッドは,前述の「Math.randomメソッド」のように,「クラス名.クラス・メソッド(引数)」と記述するだけで,実行できるメソッドです(*3)。 convertメソッドも,staticステートメントを加えたため,「Wareki.convert(引数)」と記述するだけで,和暦への変換ができるようになりました。
//2007年7月13日を「平成」形式で変換
var _day:Date = new Date(2007,6,13);
//Warekiクラスのクラス・メソッド「convert」を利用して変換
trace("変換結果は、" + Wareki.convert(_day,3));
「Wareki.convert」という形式で記述するために,見た目にも「ああ,和暦にコンバートしてるんだなあ」と,処理の内容が直観的にわかりやすくなりますね。
>>見た目にわかりにくい値をわかりやすくする「定数」...
連載新着連載目次へ >>
|