[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

コンピュータIIB(Javaプログラミング入門)第7回

目次
7.1 手続きとしてのメソッド
7.1.1 メソッドとは
7.1.2 メソッドの引数
7.2 関数としてのメソッド
7.2.1 メソッドの返り値
7.2.2 メソッドの使用例
7.3 演習7
7.4 レポート課題
7.5 参考文献
索引
値呼出し   返り値   仮引数   関数   実引数   手続き   引数   メソッド   メソッド呼出し  

7.1 手続きとしてのメソッド

7.1.1 メソッドとは

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

/*  1*/ class NameTag1 {
/*  2*/     public static void main (String[] args) {
/*  3*/         System.out.println("-------------------------");
/*  4*/         System.out.println("-------------------------");
/*  5*/         System.out.println("No.");
/*  6*/         System.out.println("-------------------------");
/*  7*/         System.out.println("Name");
/*  8*/         System.out.println();
/*  9*/         System.out.println("-------------------------");
/* 10*/         System.out.println("-------------------------");
/* 11*/     }
/* 12*/ }
b04a001@AsiaA1:~/comp2b% java NameTag1
-------------------------
-------------------------
No.
-------------------------
Name

-------------------------
-------------------------
b04a001@AsiaA1:~/comp2b%

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

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

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

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

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

methodname();

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

メソッド呼出しにおける実行の流れ
図 7.1  メソッド呼出しにおける実行の流れ

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

/*  1*/ class NameTag2 {
/*  2*/     public static void main (String[] args) {
/*  3*/         rule();
/*  4*/         rule();
/*  5*/         System.out.println("No.");
/*  6*/         rule();
/*  7*/         System.out.println("Name");
/*  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("No.");
/*  5*/         rule();
/*  6*/         System.out.println("Name");
/*  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*/ }

7.1.2 メソッドの引数

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

引数を持つメソッドは次のように定義されます。 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("No.");
/*  5*/         multiRule(1);
/*  6*/         System.out.println("Name");
/*  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*/ }

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

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

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

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


7.2 関数としてのメソッド

7.2.1 メソッドの返り値

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

一般的なプログラミングの用語では、値を返さないプログラム単位を 手続きprocedure )と呼び、値を返すプログラム単位を 関数function )と呼びます。 Javaでは、手続きも関数もメソッドで実現します。

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

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

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

return expression;

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

methodname(argument, ...)

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

次の例では、2つの数のうち、大きい方を返すメソッド max と、小さい方を返すメソッド min を定義しています。

/*  1*/ class MaxMinTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         System.out.println(max(100, 200));
/*  4*/         System.out.println(min(100, 200));
/*  5*/     }
/*  6*/     static int max (int m, int n) {
/*  7*/         if (m > n) {
/*  8*/             return m;
/*  9*/         } else {
/* 10*/             return n;
/* 11*/         }
/* 12*/     }
/* 13*/     static int min (int m, int n) {
/* 14*/         if (m < n) {
/* 15*/             return m;
/* 16*/         } else {
/* 17*/             return n;
/* 18*/         }
/* 19*/     }
/* 20*/ }
b04a001@AsiaA1:~/comp2b% java MaxMinTest
200
100
b04a001@AsiaA1:~/comp2b%

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

7.2.2 メソッドの使用例

メソッドの例として、はじめに mn 乗を計算するメソッド power を定義します。 ここで、 n ≧0 と仮定します。

メソッド power の引数は、 mn です。 このメソッドは整数を返しますので、 static int と指定します。

メソッド定義では、まず、変数 result を宣言し、1で初期化します。 そして、 for 文の中で、 result の値を nm 倍します。 最後に、 result の値を return で返します。

メソッド呼出しでは、例として、 power (2, 5), power (5, 2), power (3, 3) の3つの式について、式自身とその値を出力します。

プログラムは次の通りです。

/*  1*/ class PowerTest {
/*  2*/     public static void main (String[] args) {
/*  3*/         System.out.println("power(2, 5) is " + power(2, 5));
/*  4*/         System.out.println("power(5, 2) is " + power(5, 2));
/*  5*/         System.out.println("power(3, 3) is " + power(3, 3));
/*  6*/     }
/*  7*/     static int power (int m, int n) {
/*  8*/         int i, result = 1;
/*  9*/         for (i = 0; i < n; i++) {
/* 10*/             result = result * m;
/* 11*/         }
/* 12*/         return result;
/* 13*/     }
/* 14*/ }
b04a001@AsiaA1:~/comp2b% java PowerTest
power(2, 5) is 32
power(5, 2) is 25
power(3, 3) is 27
b04a001@AsiaA1:~/comp2b%

次の例は、階乗を計算するメソッド fact です。 ここで n の階乗とは、 n ! と表され、

n ! = 1 * 2 * ... * ( n - 1) * n

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

メソッド fact の引数は n です。 このメソッドは整数を返しますので、 static int と指定します。

メソッド定義では、まず。変数 result を宣言し、1で初期化します。 そして、 for 文の中で、 result の値を1倍し、2倍し、…、 n 倍します。 最後に、 result の値を return で返します。

メソッド呼出しでは、例として、 fact (4), fact (5), fact (6) の3つの式について、式自身とその値を出力します。

プログラムは次の通りです。

/*  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*/ }
b04a001@AsiaA1:~/comp2b% java FactTest
fact(4) is 24
fact(5) is 120
fact(6) is 720
b04a001@AsiaA1:~/comp2b%

7.3 演習7

いくつかの図形の面積を求めるメソッドを定義して、それらを呼び出すプログラムを作成してください。 図形と公式は次の通りです。

正方形の場合は、メソッドの名前を square とし、引数を length とします。 このメソッドは整数を返しますので、 static int と指定します。 メソッド定義では、式 length * length の値を return で返します。

長方形の場合のメソッド rectangle と三角形の場合のメソッド triangle も同様に定義します。 引数の順序については、長方形は長さ、幅、三角形は底辺、高さとします。

メソッド呼出しでは、例として、 square (20), rectangle (10, 30), triangle (40, 10) の3つの式について、式自身とその値を出力します。

b04a001@AsiaA1:~/comp2b% java FigureArea
square(20) is 400
rectangle(10, 30) is 300
triangle(40, 10) is 200
b04a001@AsiaA1:~/comp2b%

余力のある人は、以下の図形の面積も求めてください。

b04a001@AsiaA1:~/comp2b% java FigureArea
square(20) is 400
rectangle(10, 30) is 300
triangle(40, 10) is 200
parallelogram(10, 10) is 100
lozenge(10, 30) is 150
trapezoid(20, 30, 10) is 250
b04a001@AsiaA1:~/comp2b%

7.4 レポート課題

今日の演習7の答案(Javaプログラム)を、メールでkonishi@twcu.ac.jp宛に提出してください。 メールを送るときは、大学のパソコンを使うか、大学のメール・サーバに接続するかして、差出人が大学のメール・アドレスになるようにしてください。 メールの本文には、学生番号、氏名、科目名、授業日(6月9日)を明記してください。


7.5 参考文献


[小西ホームページ]   [目次・索引]   [前の授業]   [次の授業]

2006年6月9日更新
小西 善二郎 <konishi@twcu.ac.jp>
Copyright (C) 2006 Zenjiro Konishi. All rights reserved.