私のホームページへ - 前の授業へ - 次の授業へ

情報処理IIIA(Javaプログラミング入門)第7回

目次
  1. クラスとメソッド(1)
  2. 演習7
  3. レポート課題

クラスとメソッド(1)

Javaとオブジェクト指向プログラミング

Java言語は、オブジェクト指向プログラミングobject-oriented programming)という考え方に基づいています。 オブジェクト指向とは、簡単に言えば、操作よりもデータに注目するということです。 Javaらしいプログラムを書くには、オブジェクト指向プログラミングを理解する必要があります。 ただし、オブジェクト指向プログラミングは、比較的最近提案されたものであり、それほどやさしくありません。

Java言語では、オブジェクト指向に基づかない古典的な手法でも、ある程度プログラムが書けます。 この授業では、はじめに古典的な手法を紹介し、少しずつオブジェクト指向の考え方に慣れることにします。

メソッドとは

今、次のようなプログラムを考えます。

 1: class NameTag1 {
 2:    public static void main (String[] args) {
 3:       System.out.println("------------------------------");
 4:       System.out.println("------------------------------");
 5:       System.out.println("NAME");
 6:       System.out.println("------------------------------");
 7:       System.out.println("AFFILIATION");
 8:       System.out.println();
 9:       System.out.println("------------------------------");
10:       System.out.println("------------------------------");
11:    }
12: }
b00a001@Ampere:~/java% java NameTag1
------------------------------
------------------------------
NAME
------------------------------
AFFILIATION

------------------------------
------------------------------
b00a001@Ampere:~/java%

3行目、4行目、6行目などに、罫線を出力するという、まったく同じ処理が繰り返されています。 これらの処理に名前をつけ、その名前で処理が表せると、プログラムが書きやすくなります。 メソッドmethod)というものを用いますと、そのようなことができます。 なお、メソッドにはインスタンスメソッドinstance method)とクラスメソッドclass method)があります。 今日はクラスメソッドのみ扱います。

メソッドとは、処理のまとまりに名前をつけたものです。 メソッドを使うためには、プログラムの中でメソッドを定義しなくてはいけません。 メソッドの定義は次のような形をとります。

static void methodname () {
   statement; ...
}

これによって、処理のまとまり statement; ... に methodname という名前がつきます。

定義したメソッドを使うには、プログラムに次のような文を書きます。 これをメソッド呼び出しmethod call)とよびます。

methodname();

プログラムの中にメソッド呼び出しがありますと、実行の流れは次の図のようになります。 メソッド呼び出し f(); を実行するとき、メソッド f の定義の内容を実行し、それが終わったら、メソッド呼び出しの次から実行します。

Execution flow on a method call
図7.1 メソッド呼び出しにおける実行の流れ

上記のプログラムの場合、次のようになります。 罫線を出力するという処理に、rule という名前をつけています。 メソッド呼び出し rule(); を実行しますと、罫線が出力されます。

 1: class NameTag2 {
 2:    public static void main (String[] args) {
 3:       rule();
 4:       rule();
 5:       System.out.println("NAME");
 6:       rule();
 7:       System.out.println("AFFILIATION");
 8:       System.out.println();
 9:       rule();
10:       rule();
11:    }
12:    static void rule () {
13:       System.out.println("------------------------------");
14:    }
15: }

メソッド定義の中では、他のメソッドを使うこともできます。 次の例では、罫線を出力するメソッド rule を使って、二重の罫線を出力するメソッド doubleRule を定義しています。

 1: class NameTag3 {
 2:    public static void main (String[] args) {
 3:       doubleRule();
 4:       System.out.println("NAME");
 5:       rule();
 6:       System.out.println("AFFILIATION");
 7:       System.out.println();
 8:       doubleRule();
 9:    }
10:    static void rule () {
11:       System.out.println("------------------------------");
12:    }
13:    static void doubleRule () {
14:       rule();
15:       rule();
16:    }
17: }

メソッドの引数

メソッドには引数argument)を与えることができます。 引数とは、メソッドに対する入力データだと思ってください。 なお、引数はパラメタparameter)ともよばれます。

引数を持つメソッドは次のように定義されます。 argument の部分に、引数を表す変数を書きます。

static void methodname (int argument, ...) {
   statement; ...
}

このようなメソッドを呼び出すには、次のように書きます。 argument の部分に、引数となる式を書きます。

methodname(argument, ...);

メソッド定義の引数を仮引数formal argument)とよび、メソッド呼び出しの引数を実引数actual argument)とよびます。 メソッドは呼び出されますと、仮引数(変数)に実引数(式)の値が代入され、メソッド定義の内容が実行されます。

次の例では、n 重の罫線を出力するメソッド multiRule を定義しています。 メソッド呼び出し multiRule(2); が実行されますと、メソッド定義の仮引数 n に実引数の値2が代入され、罫線の出力を2回繰り返すようにメソッドが実行されます。 なお、メソッド定義の中でも変数が宣言できることに注意してください。 (11行目)

 1: class NameTag4 {
 2:    public static void main (String[] args) {
 3:       multiRule(2);
 4:       System.out.println("NAME");
 5:       multiRule(1);
 6:       System.out.println("AFFILIATION");
 7:       System.out.println();
 8:       multiRule(2);
 9:    }
10:    static void multiRule (int n) {
11:       int i;
12:       for (i = 0; i < n; i++) {
13:          System.out.println("------------------------------");
14:       }
15:    }
16: }

メソッドの返り値

メソッドは、まとまった処理をするだけでなく、何らかの計算をして、その値を呼び出し側に返すこともできます。 そのような値を、メソッドの返り値return value)とよびます。 返り値は、メソッドの出力データと考えてください。

整数(int 型)を返り値に持つメソッドは、次のように定義されます。

static int methodname (int argument, ...) {
   statement; ...
}

これまでの、返り値を持たないメソッド定義での void の代わりに、int と書きます。 この定義の中に、少なくとも一つ return 文を書きます。 return 文は次のような形をとり、式 expression の値がこのメソッドの返り値になります。

return expression;

返り値を持つメソッドは、次のような式で呼び出します。

methodname(argument, ...)

式の中にメソッド呼び出しがありますと、メソッド定義の内容が実行されます。 そして、その中の return 文が実行されますと、メソッドの実行は終了され、return 文の式の値が呼び出し側に返されます。

次の例では、二つの数のうち大きい方を返すメソッド max を定義しています。 返り値を持つメソッドは、式として呼び出されることに注意してください。

 1: class MaxTest {
 2:    public static void main (String[] args) {
 3:       System.out.println(max(100, 200));
 4:       System.out.println(100 + max(20 + 30, 30));
 5:    }
 6:    static int max (int m, int n) {
 7:       if (m > n) {
 8:          return m;
 9:       } else {
10:          return n;
11:       }
12:    }
13: }
b00a001@Ampere:~/java% java MaxTest
200
150
b00a001@Ampere:~/java%

注意: 返り値を持たないメソッドでも return 文が使えます。 この場合、式を抜いた return; という形になります。 メソッドの実行中に return 文を実行しますと、そこでメソッドの実行を終了します。

引数の渡し方

メソッドを呼び出すとき、仮引数には実引数の値が代入されます。 詳しく言いますと、呼び出しの際、仮引数の変数が用意され、そこに実引数の値のコピーが格納されます。 このような呼び出し方を、値呼び出しcall by value)とよびます。

次のプログラムは、引数を0にしようとしてもうまくいかない例です。

 1: class BindingTest {
 2:    public static void main (String[] args) {
 3:       int x = 100;
 4:       zero(x);
 5:       System.out.println(x);
 6:    }
 7:    static void zero (int n) {
 8:       n = 0;
 9:    }
10: }
b00a001@Ampere:~/java% java BindingTest
100
b00a001@Ampere:~/java%

4行目のメソッド呼び出し zero(x); を実行しますと、メソッド定義の7行目の変数 n にデータ100のコピーが格納されます。 コピーを0に置き換えてメソッドを終了しますので、5行目の変数 x の値は100のままなのです。

メソッドの例

メソッドの例として、階乗を計算するメソッド fact を定義して、いくつかの階乗を計算します。 ここで n の階乗とは、n ! と表され、

(7.1) n ! = 1×2×…×(n - 1)×n

と定義されるものです。 (n≧0 と仮定しています。)

 1: class FactTest {
 2:    public static void main (String[] args) {
 3:       System.out.println("fact(4) is " + fact(4));
 4:       System.out.println("fact(5) is " + fact(5));
 5:       System.out.println("fact(6) is " + fact(6));
 6:    }
 7:    static int fact (int n) {
 8:       int i, result = 1;
 9:       for (i = 1; i <= n; i++) {
10:          result = result * i;
11:       }
12:       return result;
13:    }
14: }
b00a001@Ampere:~/java% java FactTest
fact(4) is 24
fact(5) is 120
fact(6) is 720
b00a001@Ampere:~/java%

演習7

順列とは、n 個の中から r 個並べる場合の数のことです。 これは n P r と表され、

(7.2) n P r = n×(n - 1)×…×(n - r + 1)

と計算できます。 また、次のようにも計算できます。

(7.3) n P r = n ! / (n - r) !

式 (7.2) にしたがって順列を計算するメソッド perm2 と、式 (7.3) にしたがって順列を計算するメソッド perm3 を定義し、以下のようにいくつかの順列を計算するプログラムを作成してください。 (上記の fact メソッドを用います。 また、nr≧0 と仮定してください。)

b00a001@Ampere:~/java% java PermTest
perm2(5, 2) is 20
perm3(5, 2) is 20
perm2(6, 4) is 360
perm3(6, 4) is 360
b00a001@Ampere:~/java%

レポート課題

今日の演習7にしたがってJavaプログラムを作成し、konishi@twcu.ac.jpあてにメールでそのプログラムを提出してください。 メールには、学生番号、氏名、科目名、授業の日付けを明記してください。


私のホームページへ - 前の授業へ - 次の授業へ

このページの複製は、東京女子大学学内に限り許可します。 このページへのリンクを許可します。
2000年11月4日更新
製作・著作:小西善二郎<konishi@twcu.ac.jp>