第 2 章 Java 言語の基本的な文法 I 5
2.74 CircleArea3 ( クラスメソッドでの円の面積2 )
public class CircleArea3 {
public static void main(String[] args) { for(int r=1; r<=10; r++) {
printCircleArea( r );
} }
// 円の面積情報を出力するメソッド
static void printCircleArea( int r ) { double area = circleArea( r );
System.out.printf( "半径=%2d の円の面積は、%8.4f です%n", r, area );
}
// 半径 radius の円の面積を返すメソッド
static double circleArea( double radius ) { double area = radius * radius * Math.PI;
return area;
} }
今回のプログラムでは、さらに円の面積計算を分離しました。
先のプログラムと見比べてみて下さい。circleArea メソッドの宣言部には void の代わりに doubleと書かれ ていますね。これが戻り値の型です。つまり、半径から円の面積を計算して返すメソッド circleArea() の戻り 値は実数だ!というわけです。printCircleArea メソッドはcircleArea メソッドの引数に半径の値を渡して円 の面積を計算させ、その結果を返してもらって変数 area に代入し、コンソールに結果を出力しています。一方、
circleArea メソッドは、引数に半径を与えられながら呼び出され、面積を計算し、自分を呼び出したメソッド (こ
の場合 printCircleArea())に計算結果を戻しています。その計算結果を戻すという命令が return area; です。
return命令の後ろに戻したい値の入った変数もしくは式を書きます。ちなみに、戻り値がvoidのprintCircleArea メソッドの方には return命令がありません(returnのあるvoid メソッドも実は「有り」なのですが、その話は先 の節で)。
さて、プログラムCircleArea3 とCircleArea2 を比較してもらって、もう1つ気付くことがあるかと思います。
circleArea() メソッドの宣言と printCircleArea() での circleArea() メソッドの呼び出しが一致していない (引数の変数の型と名前が異なる)ことです。大丈夫なのでしょうか?
大丈夫です。まず、変数名が異なる件について、これって似たようなこと以前に学びましたよね。double型変数に int型リテラルを代入はできるけど、逆はダメ!という話です。同じことが、この引数でも言えるのです。circleArea
側でdoubleで受取る!と宣言しているのなら、渡す値は、整数型でも実数型でも代入できて大丈夫なわけです。
では、質問!上のプログラムにもう1つ次のメソッドを加えたらプログラムはどう動くでしょうか?
// 半径 radius の円の面積を返すメソッド2 static double circleArea( int radius ) {
System.out.println( "新たなメソッドが呼ばれた" );
double area = radius * radius * Math.PI;
return area;
}
新たなメソッドもcircleArea という名前のメソッドです。違うのは、引数の型だけ。実際にプログラムに追加して 動かしてみると、想像通り、新たに追加したメソッドの方を呼び出しています。
Java では、同じ名前のメソッドを複数持つことが許されています。ただし、次のルールが満たされないとエラーに なります。
• 引数の個数が違う
• 引数の個数が同じでも、いずれかの型が異なる
例えば、引数の型と個数は同じだけど戻り値の型が違うメソッド2つでは、ダメです。なぜなら、呼び出す側から見 たとき見た目が同じで区別できない。今回のように、引数の個数が等しく1個で、でも型が違う、というのなら呼び出 す側から、最も適合するメソッドを選択することが可能なわけです。例えば、main側で半径の変数rが実数型に変更
されたら、呼び出されるメソッドは最初に在ったcircleAreaメソッドとなります(int型の引数に実数を代入できな いので)。
問題 2.18.1. 次の2つのメソッドが共存できるか、できないかを答えなさい。
1. double method(int a, int b)とdouble method(int x, int y) 2. double method(int a, int b)とint method(int a, int b)
3. double method(int a, double b)とdouble method(double a, int b) 4. double method(int a, int b)とdouble method(int a)
5. double method(int a, int b)とdouble method(double x, double y) 6. double method(int a, int b)とvoid method(int a, int b)
この問題で、設問3がちょっとモヤモヤする設問ですね。この場合、先のルールに基けば共存は可能です。ただ、も
しmethod( 1, 2 ); のように両引数を整数値で呼んだ場合、いずれのメソッドも選択可能になってしまい、呼び出し側
でエラーになってしまいます。呼び出す際に引数を共に整数としないなら、問題なく共存できるということで、答えと しては「共存できる」だけど、ニュアンスは「どちらとも言えない」ですかね。
では、次は呼び出す側と呼び出される側で引数の変数名が異なる件について。
Aさん 「実数を2つ渡すので、それらの大きい方を返してくれるメソッド作ってくれる?」
Bくん 「よっしゃ!じゃぁ、double max(double, double)なるメソッド作るから、よろしく!」
Bくん、戻り値と引数2つの型だけAさんに伝えていますね。細かい変数名などは、それぞれが自由に作れて、ただし 引数の個数と型、そして戻り値の型は、事前に了解しておく。こうしてプログラムを分担して作成できるわけですね。
ところで、続いて二人の間で次のような会話が:
Aさん 「整数を2つ渡すので、大きい順に並び替えするメソッド作ってくれる?」
Bくん 「よっしゃ!じゃぁ、void swap(int, int)なるメソッド作るから、よろしく!」
で、Bくん、2つの数の交換は2.8章でSwapValues.javaを作った経験からすぐ出来上がって、彼らの合作プログラ ムが次のようにできました。
ソースコード2.75 SwapValues2.java (クラスメソッドで数の交換できる?)