青森の全国高校文化祭に写真部門で参加したこうしろうは,恐山や三内丸山遺跡を撮りまくって帰ってきた。その後も高校生対象の写真教室に写真部の仲間と一緒にまめに参加している。富山県の五箇山から岐阜県白川郷へと続く合掌集落で開催された一泊二日の写真教室にも参加した。
富山県人には割りと身近な世界遺産を写した一枚である。晴れ間が出てきたのか靄が心地よい。夏場も良いが冬の雪深い合掌集落の写真を見ると,生活の大変さと人間のたくましさを思い知らされる。真冬にあそこに写真を撮りに行った写真家にも感心する。
カメラの腕前が上がったのかどうかはわからないが,撮影時のセッティングと構図にはうるさくなった。旧式のレーザープリンタみたいなもので1枚目が出てくるまでに暇が掛かるのだ。
コンピュータよりもカメラ好きになったのか,Eclipseを使ったJavaの勉強はなかなか進みが遅い。Javaのオブジェクト指向をざっと学ぶのに1ヵ月間かかった。
この日は,インスタンス変数とクラス変数の違いを学ぶのだが,その前にEclipseの機能を1つ確認した。
たとえば「System.out」と入力後,Ctrl+Spaceを押すとprintやprintlnというメソッドが選択肢として表示され,エンターキーで選択できるので,入力の手間が省けることは以前にも書いたが,何もないところで,Ctrl+Spaceキーを押しても入力支援機能が働く。
何も入力していない行で,Ctrl+Spaceキーを押すと,変数名やメソッド,クラス名が選択肢として表示される。長いわかりやすい変数名を付けても入力は簡単なのだ。
さて,本日のテーマは,クラス変数とインスタンス変数である。どちらの変数もクラス内に定義する。メソッドの内側に定義すると,メソッド内でのみ有効なローカル変数になってしまうので,クラス変数とインスタンス変数はメソッドの外に書く。staticを付けて宣言した変数がクラス変数になる。具体的にプログラムでみていこう。
---------------------------------------------------------- public class DefVariable { int i = 0; static int clsi = 0; public void incre(){ i++; clsi++; } public void dispi(){ System.out.println(i); } public void dispClsi(){ System.out.println(clsi); } } ----------------------------------------------------------DefVariableクラスで,iとstaticキーワードをつけたclsiを宣言している。staticは「静的な」という意味である。iとclsiに1を足すincreメソッドとiとclsiの値を表示するdispiメソッドとdispClsiメソッドを持つクラスである。
次のChkVariableクラスの中で,DefVariableのインスタンスを生成し,incre メソッドを実行した後,iとclsiの値を表示させている。
---------------------------------------------------------- public class ChkVariable { public static void main(String[] args) { DefVariable cls1,cls2; int i; cls1 = new DefVariable(); cls2 = new DefVariable(); for(i=0;i<5;i++){ cls1.incre(); } System.out.print("cls1のインスタンス変数\t i: \t"); cls1.dispi(); System.out.print("cls1のクラス変数\t clsi: \t"); cls1.dispClsi(); for(i=0;i<10;i++){ cls2.incre(); } System.out.print("cls2のインスタンス変数\t i: \t"); cls2.dispi(); System.out.print("cls2のクラス変数\t clsi: \t"); cls2.dispClsi(); } } ----------------------------------------------------------ChkVariableクラスのmainメソッドでは,DefVariableクラスのインスタンスをcls1,cls2と2つ作成している。まず,cls1のincreメソッドを5回呼び出した後に,dispiメソッドでインスタンス変数iの値を表示し,次にクラス変数clsiの値をdispClsiメソッドで表示させている。
それから,cls2のincreメソッドを10回呼び出し,同じようにインスタンス変数iの値とclsiの値を表示させている。出力結果は以下のようになる。
---------------------------------------------------------- cls1のインスタンス変数 i: 5 cls1のクラス変数 clsi: 5 cls2のインスタンス変数 i: 10 cls2のクラス変数 clsi: 15 ----------------------------------------------------------みて,みて,みて。あーら,不思議!DefVariable クラスでは変数の定義と同時に,iもclsi も0で初期化しているはずなのにclsiの値が15になっている。なぜでしょう?
インスタンス変数は,インスタンスに所属するインスタンスに固有な変数なのだが,クラス変数はクラスに所属するのだ。つまり,クラス変数はクラスで一つだけ存在するのである。だから,逆にいうと,クラス変数はインスタンスを生成しないでも使うことができるのだ。
ちなみに,ChkVariable クラスのmainメソッドでint i;と宣言している変数iはmainメソッドでのみ有効なローカル変数である。