Part2では,Javaにおけるオブジェクト指向プログラミングに基本を学びます。まずはひな型であるクラスによってインスタンスが生成されることを理解してください。
まず,オブジェクト指向におけるクラスとは何かをざっと説明しておきましょう。
クラスとは,オブジェクト指向の考え方に基づいてデータ(属性)と手続き(振る舞い)を一つにまとめたものです。オブジェクト指向プログラミングでは,クラスがプログラムの基本の単位になります。
プログラマは,あらかじめ用意されているクラスや,自分が作成したクラスを組み合わせてプログラムを作成します。JavaではC++と異なり,プログラムで利用するすべてのデータと手続きは,いずれかのクラスに属していなければなりません。作成したプログラムを実行すると,クラスをひな型にして生成されたオブジェクト(Javaでは「インスタンス」と呼びます)が,互いにメッセージをやり取りしながら処理を進めていきます(図1)。
ここでは簡単なクラスを作成し,オブジェクト指向プログラミングを実践してみます。インスタンスの生成やメッセージのやり取り(「メッセージ・パッシング」と言います)を,感覚で理解できることを目指してやってみてください。
まずはクラスを二つに分けてみよう
リスト1は,Javaで記述した金運占いプログラムです。
public class Money {
public static void main(String[] args) {
double d = Math.random();
int r = (int)(d * 10);
System.out.println("あなたの今日の金運は・・・\n");
System.out.println(" 貧乏 普通 お金持ち");
System.out.print("-> ");
for(int i = 0; i < r; i++) {
System.out.print("-> ");
}
System.out.println("*");
}
}
Moneyクラス一つで構成するこのプログラムは,オブジェクト指向らしいプログラムとは言えません。このクラスを二つに分けて,インスタンス生成やメッセージ・パッシングによって処理を進めるように改良してみましょう。
その前に,リスト1のプログラムの処理の流れについて説明しておきます。
(1)randomメソッドを呼び出して,0以上1未満の乱数を得る
(2)得られた乱数に10をかけてからint型に変更し,0から9までの整数にする
(3)(2)で得た整数の回数だけ矢印を表示する
(4)最後に「*」を表示して矢印の先頭とする
(1)で得られた乱数の値が大きいほど,表示される矢印が長くなる(金運が良いと表示される)仕組みです。
リスト1では一つのクラスにすべての処理を記述していますが,こうしてみるといくつかのクラスに処理を分割できそうです。まずは,乱数を得て整数にするクラスと,結果を表示するクラスの二つに分けてみましょう。
リスト2はリスト1から結果を表示する部分を切り出したクラスです。と言っても,コードをそのまま切り出してクラスにしているわけではありません。大切なのは先頭からの3行です。4行目以降はリスト1と変わらないので説明しません。
1行目を見てください。ここではMoney01という名のクラスを作るということを宣言しています。リスト1の先頭と同じ意味を持っていますが,先頭に修飾子publicが省略されています。クラスの宣言で修飾子を省略した場合は,同じパッケージ内からだけアクセスできるクラスになり,public修飾子を付けると外部のパッケージからもアクセスできるクラスになります。パッケージはここでは,Windowsにおけるフォルダと同義と考えていただいて構いません。すなわち,Money01クラスを利用するクラスのプログラムは,Money01クラスを格納したのと同じフォルダに入れておく必要があります。
次は2行目です。ここではこのクラスで使用する変数を宣言しています。リスト1と比べてみると,変数を宣言する位置がちょっと違いますね。リスト1の変数(dとr)はメソッドの中で宣言していますが,リスト2の変数(r)はメソッドの外で宣言しています。メソッドの外で宣言した変数はフィールドと呼び,ほかのクラスから参照できます。
フィールドには,インスタンスを生成してはじめて利用できるようになるインスタンス変数と,インスタンスを生成しなくても利用できるクラス変数の2種類があります。リスト2のように型の前に何も付けずに変数を宣言するとインスタンス変数になります。
最後に3行目を見てください。メソッドの宣言をしています。フィールドとメソッドをまとめてクラスのメンバーと呼ぶこともあります。メソッドの基本的な書式は以下の通りです。
修飾子 戻り値の型 メソッド名 (引数1, 引数2,…){
処理
return 戻り値;
}
リスト1とリスト2を見比べると,リスト1には修飾子としてpublic staticが付いていることに気づきます。public修飾子を付けたメソッドは外部のパッケージのクラスからも利用でき,省略したメソッドはパッケージの中からだけ利用できるのは,フィールドの場合と同じです。
さらに,フィールドと同様にメソッドにも,インスタンスを生成してはじめて利用できるようになるインスタンス・メソッドと,インスタンスを生成しなくても利用できるクラス・メソッドの2種類があります。static修飾子を付けるとクラス・メソッドになり,付けないとインスタンス・メソッドになります。リスト2で宣言しているメソッドはインスタンス・メソッドです。