Javaプログラミング基礎

講義資料

メソッド

今回も引き続きメソッドについて学びます。 メソッドには、メソッド内で行った計算結果を実行元に返す機能があります。 この機能を用いると、単にひとまとめにした仕事を行うだけでなく、 計算の結果や処理の成否などさまざまな情報をメソッドを介してやり取りすることができます。

処理の結果を返すメソッド

Java のメソッドは、単に仕事の分割を行うだけでなく、 処理や計算を行った結果を実行元に返すことができます。 この機能は、数学の関数と対比して考えると理解の助けになるはずです。 次の数式を考えてみましょう。

y = f(x)

Java のプログラムではこの式は、 変数 x の値をメソッド f に渡し、 f の中で計算や処理を行った結果を変数 y に代入する、 という意味になります。 メソッド f の中身に行うべき計算の方法を書いておきます。

ここで、n 個の中から m 個を選ぶ組み合わせの数 nm の計算を考えましょう。 nm は次のような式で求まります。

nm = n! / ( m! * (n - m)! )

この計算をメソッドを用いずに書くと次のようになります。

// n! の計算
int nx = 1;
for (i = 1; i <= n; i = i + 1)
    nx = nx * i;

// m! の計算
int mx = 1;
for (i = 1; i <= m; i = i + 1)
    mx = mx * i;

// (n-m)! の計算
int nmx = 1;
for (i = 1; i <= n - m; i = i + 1)
    nmx = nmx * i;

// n_C_m の計算
combination = nx / (mx * nmx);

このプログラムでは階乗の計算が 3 回現れます。 3 回とも計算のやり方は同じですが、どの値の階乗を求めるのか、 また計算結果をどの変数に入れるのかが異なるため、 ほとんど同じ形のプログラムを 3 回書かなければなりません。

このような場合、階乗を計算する仕事をメソッドとして、 ひとまとめにしてしまえば良いのです。 階乗を求めるメソッドに fact という名前をつけたとすると、 上のプログラムは、次のように簡単なものになります。

int nx = fact(n);
int mx = fact(m);
int nmx = fact(n - m);
combination = nx / mx * nmx;

メソッド fact の定義は、次のように書きます。

static int fact(int x) {
    int f = 1;
    for (int i = 1; i <= x; i++)
        f = f * i;
    return f;
}

このメソッドの引数は x です。 メソッドが実行されたとき、 x には、メソッドの実行元から渡された引数の値が入っています。 メソッド内では x の値をもとにして、 変数 f を使って階乗を計算しています。

メソッドの最後に return 文があります。 return文は f (すなわち計算された階乗の値) を実行元に返しています。

一方、メソッド fact の実行元では、 「fact(引数)」は、数値や変数などと同様に式の一部として使うことができます。 例えば a = fact(3) + 10 のように書くと、 まず 3 の階乗が計算され 6 を得て、さらに 10 を加えた値が変数 a に代入されることになります。

メソッドを用いると 複雑な計算をひとまとめにして独立させることができ、 同じ計算を複数回書くという手間を省くことができます。 そして、メソッドを実行することで何回でも計算を行うことができます。

メソッドの宣言

結果の値を返すメソッドの宣言の形式は次のとおりです。

    static  結果の型  メソッド名  ( 引数の宣言 )  {
        .... 
        メソッドの本体
        .... 
    }

「結果の型」は、メソッドがどんな型の値を返すのかを設定します。 整数を返すのであれば int 、 浮動小数点数を返すのであれば double と書きます。 また、結果を返さないメソッドの場合は void と書きます。

return 文

メソッドから値を返すことを記述するための文が return 文です。 return 文の形式は次のとおりです。

return  式 ;

return の後に返したい値を求める式を書きます。 この式は、 そのメソッドの先頭で宣言した結果の値と同じ型の式である必要があります。

値を返さないメソッド、すなわちメソッドの宣言の先頭で void と書いたメソッドの場合、 単に return; と書くとそのメソッドの処理は終了します。 return の後の式は書く必要ありません。 また、 return 文を省略することもできます (前回のプログラムがそうでしたね)。 メソッド宣言の中カッコの最後まで処理が達すれば、そのメソッドの処理は終了します。

ただし、値を返すメソッドの場合 return 文を省略することはできません。

return 文を実行すると、その時点でメソッドの実行は終わりになり、 メソッドを実行した相手にプログラムの処理が戻ります。 return という言葉には「返す」と「戻る」両方の意味が含まれている と考えれば良いでしょう。

例題1: 組み合わせ数の計算

先ほど取り上げた nm の計算をするプログラムの全体を示します。 ファイル名は Combination.java とします。

class Combination {
    public static void main(String[] args) {
        int n = 5;
        int m = 2;

        int combination = fact(n) / (fact(m) * fact(n - m));
        System.out.println("Combination of " + n + ", " + m + " = " + combination);
    }

    static int fact(int x) {
        int f = 1;

        for (int i = 1; i <= x; i++)
            f = f * i;
        return f;
    }
}

例題2: 2 つの数の大きい方 (最大値) を返すメソッド

2 つの数の大きい方を求める計算をメソッドとして独立させます。 このメソッドを利用して、 3 つの変数の最大値を求めるプログラムを書いてみます。 ファイル名は Max3d.java とします。

class Max3d {
    public static void main(String[] args) {
        int x = 5;
        int y = 2;
        int z = 3;

        System.out.println("最大値は " + maximum(x, maximum(y, z)) + " です。");
    }

    static int maximum(int a, int b) {
        if (a > b)
            return a;
        else
            return b;
    }
}

メソッド maximum の動きは単純です。 2 つの数 a と b を比較し、大きい方の値を返します。 if 文でどちらの場合に進んでも必ず return 文で値を返すようにしています。

このメソッドを利用すれば main メソッドは簡単です。 まず、yz の最大値を求め、 その結果と x の最大値を求めれば良いのです。

System.out.println の中に直接 maximum(x, maximum(y, z)) を書いています。 System.out.println の中には、 「式」を書くことができるという決まりがあります。 Java の世界では、変数や数値だけではなく、 メソッド maximum の実行も何らかの値を持った式と見なされます。