目次 | 索引 |
---|---|
今、次のようなプログラムを考えます。
/* 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:~/java% java NameTag1 ------------------------- ------------------------- No. ------------------------- Name ------------------------- ------------------------- b04a001@AsiaA1:~/java%
3行目、4行目、6行目などに、罫線を出力するという、まったく同じ処理が繰り返されています。 これらの処理に名前をつけ、その名前で処理が表せますと、プログラムが読みやすく、かつ書きやすくなります。 メソッドというものを用いますと、そのようなことができます。 なお、メソッドには「インスタンスメソッド」というものと「クラスメソッド」というものがあります。 今日はクラスメソッドのみ扱います。
メソッド ( method ) とは、処理のまとまりに名前をつけたものです。 メソッドを使うためには、プログラムの中でメソッドを定義しなくてはいけません。 メソッドの定義は次のような形をとります。
static void methodname () { statement; ... }
これによって、処理のまとまり
statement
;
...
に
methodname
という名前がつきます。
定義したメソッドを使うには、プログラムに次のような文を書きます。 これを メソッド呼出し ( method call ) とよびます。
methodname();
プログラムの中にメソッド呼出しがありますと、実行の流れは次の図のようになります。
メソッド呼出し
f();
を実行するとき、メソッド
f
の定義の内容を実行し、それが終わったら、メソッド呼出しの次から実行します。
上記のプログラムの場合、次のようになります。
罫線を出力するという処理に、
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*/ }
メソッドには引数を与えることができます。 引数 ( 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:~/java% java BindingTest 100 b04a001@AsiaA1:~/java%
4行目のメソッド呼出し
setZero(x);
を実行しますと、メソッド定義の7行目の変数
n
にデータ100のコピーが格納されます。
コピーを0に置き換えてメソッドを終了しますので、5行目の変数
x
の値は100のままなのです。
メソッドは、まとまった処理をするだけでなく、何らかの計算をして、その値を呼び出し側に返すこともできます。 そのような値を、メソッドの 返り値 ( return value ) とよびます。 返り値は、メソッドの出力データと考えてください。
一般的なプログラミングの用語では、値を返さないプログラム単位を 手続き ( procedure )と呼び、値を返すプログラム単位を 関数 ( function )と呼びます。 Javaでは、手続きも関数もメソッドで実現します。
整数(
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*/ }
b04a001@AsiaA1:~/java% java MaxTest 200 150 b04a001@AsiaA1:~/java%
注意:
返り値を持たないメソッドでも
return
文が使えます。
この場合、式を抜いた
return;
という形になります。
メソッドの実行中に
return
文を実行しますと、そこでメソッドの実行を終了します。
メソッドの例として、はじめに m の n 乗を計算するメソッド power を定義します。 ここで、 n ≧0 と仮定します。
メソッド
power
の引数は、
m
と
n
です。
このメソッドは整数を返しますので、
static int
と指定します。
メソッド定義のアルゴリズムは次のようになります。
return
で返す。
メソッド呼出しのアルゴリズムは次のようになります。
プログラムは以下のようになります。
/* 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:~/java% java PowerTest power(2, 5) is 32 power(5, 2) is 25 power(3, 3) is 27 b04a001@AsiaA1:~/java%
次の例は、階乗を計算するメソッド fact です。 ここで n の階乗とは、 n ! と表され、
n ! = 1×2×…×( n - 1)× n
と定義されるものです。 ( n ≧0 と仮定しています。)
メソッド
fact
の引数は
n
です。
このメソッドは整数を返しますので、
static int
と指定します。
メソッド定義のアルゴリズムは次のようになります。
return
で返す。
メソッド呼出しのアルゴリズムは次のようになります。
プログラムは以下のようになります。
/* 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:~/java% java FactTest fact(4) is 24 fact(5) is 120 fact(6) is 720 b04a001@AsiaA1:~/java%
3つの整数の中間値を求めるメソッド middle を定義して、これを呼び出すプログラムを作成してください。 ここで、3つの整数の中間値とは、最大値一つと最小値一つを取り除いて残る数のことです。
メソッド
middle
の引数は、
x
,
y
,
z
です。
このメソッドは整数を返しますので、
static int
と指定します。
メソッド定義のアルゴリズムは次のようにします。
return
で返す。
return
で返す。
return
で返す。
return
で返す。
return
で返す。
メソッド呼出しのアルゴリズムは次のようにします。
このアルゴリズムをプログラムにしてください。
b04a001@AsiaA1:~/java% java MiddleTest middle(10, 20, 30) is 20 middle(50, 60, 40) is 50 middle(70, 90, 80) is 80 b04a001@AsiaA1:~/java%
余力のある人は、5つの
return
文を3つにまとめてください。
今日の演習7に従ってJavaプログラムを作成し、そのプログラムをkonishi@twcu.ac.jpあてにメールで提出してください。 メールには、学生番号、氏名、科目名、授業日(6/4)を明記してください。