「static」でクラス共有の変数・メソッドを使いこなせ!:【改訂版】Eclipseではじめるプログラミング(11)(1/3 ページ)
これからプログラミングを学習したい方、Javaは難しそうでとっつきづらいという方のためのJavaプログラミング超入門連載です。最新のEclipse 3.4とJava 6を使い大幅に情報量を増やした、連載「Eclipseではじめるプログラミング」の改訂版となります
「static」でクラス共通の性質や振る舞いを定義
Javaで開発をしていると、クラスに共通の性質や振る舞いを持たせて定義をしたくなる場面があります。そんなときは、キーワードの「static」(静的)を使って、「クラス変数」「クラスメソッド」といわれるものをクラス内に宣言します。クラス変数やクラスメソッドは、クラス共通で利用できるため、うまく使えば大変便利です。一方で意味を理解しないで使うと、使いにくいクラスが出来上がってしまいます。
今回は、staticについて解説します。このキーワードを理解すると、インスタンスのフィールド(変数)やメソッドと、クラスのフィールドやメソッドとが、どう違うのか分かるようになります。
EclipseでJavaプログラミングを始める準備がまだの方は、連載第1回の「Eclipse 3.4で超簡単Javaプログラミング基礎入門」で準備をしておいてください。
アプリケーションの情報を利用するサンプル
設定ファイルやコマンド実行時のパラメータで指定された設定情報を利用するアプリケーションというのはよくありますが、この設定情報として与えられた値は、プログラム共通で利用するものです。
この設定情報を表現するクラスを作成することを考えてみましょう。クラス名は「AppInfo」とします。設定情報としては、アプリケーション名、バージョン、実行モード(パフォーマンス優先、省電力)、といった値を指定できるとします。これまでの知識からクラスを作成すると、次のようなコードになります。前回の「Javaの実案件に必須のパッケージとインポートを知る」で解説した「パッケージ」を早速使って、「sample11.app1」というパッケージのクラスとしています。
本稿では、パッケージと対応するフォルダ名を「sample11/app1/」のように表記することにします。
package sample11.app1; class AppInfo { String appName; // アプリケーション名 int version; // バージョン int mode; // 実行モード 0:パフォーマンス優先、1:省電力 AppInfo(String n, int v, int m) { appName = n; version = v; mode = m; } }
ここで、このクラスに保持された情報を、アプリケーション内に含まれるあるクラスから参照するとします。例えば、アプリケーション名とメッセージを表示するプログラムから参照するとして、次のようなクラスを用意します。アプリケーションはAppクラスで表現し、メッセージを表示するプログラムはMessageクラスで表現します。どちらもsample11.app1パッケージ内に作成します。
package sample11.app1; class App { public static void main(String[] args) { AppInfo appInfo = new AppInfo("サンプルアプリ", 1, 0); Message message = new Message(appInfo); message.print("Hello"); } }
package sample11.app1; class Message { AppInfo appInfo; Message(AppInfo a) { appInfo = a; } void print(String message) { System.out.println("[" + appInfo.appName + "]"); System.out.println(message); } }
sample11.app1パッケージのAppクラスを実行すると、次のような結果となります。
[サンプルアプリ] Hello
計算するクラスを追加すると?
さて、ここで何かを計算するクラスを追加して、そのクラスが計算結果を表示するときにも、同じようにアプリケーション名を表示するようにしたいとします。ここでは例として、1+2を計算するCalcクラスを用意してみましょう。例えば、次のようなソースコードになります。
package sample11.app2; class Calc { void exec(AppInfo appInfo) { System.out.println("[" + appInfo.appName + "]"); System.out.println(1+2); } }
Eclipse上で、sample11.app1パッケージをマウス右ボタンクリックをして表示されるメニューで[コピー]を指定し、その後、再びsample11.app1パッケージをマウス右ボタンクリックして表示されるメニューで[貼り付け]を指定します。すると、張り付けるパッケージ名を入力するダイアログが表示されるので、「sample11.app2」と入力し[OK]をクリックします。できたsample11.app2パッケージへ、Calcクラスを追加し、Appクラスは修正します。
Appクラスは、次のように変更します。「Calcクラスのインスタンスcalcを生成して、calcのexecメソッドを呼び出す」という処理を追加しただけです。
package sample11.app2; class App { public static void main(String[] args) { AppInfo appInfo = new AppInfo("サンプルアプリ", 1, 0); Message message = new Message(appInfo); message.print("Hello"); Calc calc = new Calc(); calc.exec(appInfo); } }
sample11.app2パッケージのAppクラスを実行すると、次のような結果となります。
[サンプルアプリ] Hello [サンプルアプリ] 3
ここで、sample11.app2パッケージのAppクラスのプログラムを見直してみましょう。AppInfoクラスのインスタンスは同じものがそのまま、各クラスのインスタンスから利用されています。Messageクラスでは、インスタンス生成時にコンストラクタへ渡されていますが、Calcクラスではexecメソッドのパラメータとして渡されています。インスタンスappInfoの渡され方には違いがありますが、同じものが利用されていることに変わりはありません。
このように、なんらかの方法で、インスタンスappInfoは、これを利用するクラスへ渡されないと使えないのです。
共通で使われてもいい内容をもっと簡単に使うには?
ところで、このアプリケーションでは、appInfoの内容は変更されず、共通で使われてもいい内容です。しかし、いまのアプリケーションのクラス構成では、appInfoを利用するクラスは、何らかの方法でappInfoを渡されないと使えません。当たり前のことなのですが、もっと簡単にappInfoを利用する方法はないのでしょうか。
そんなときのために、Javaでは「クラス変数」というものが使えます。次ページでは、その「クラス変数」そして、「クラスメソッド」や「final」キーワードについて説明します。
Copyright © ITmedia, Inc. All Rights Reserved.