メソッドの定義と呼び出し

ファイルはzipフォルダに納められています。
解凍ソフト(Aladdin Expander等)を使って解凍して下さい。

ユーザ定義メソッド

メソッドを使う利点

メソッドとは、一言で言うと「処理のまとまり」です。
メソッドを使った場合、以下の様な利点が有ります。

プログラムを部品化し、見た目も整理されたプログラムに可能
既に出来ているメソッドを使う事で、開発のコストと制作期間を短縮可能

予めコンパイラから提供されているメソッドを、皆さんが自分で全部作らなければならないとしたら、莫大な時間が懸かって終います。

メソッドの定義と呼び出し

メソッドを作る事をメソッドの定義、其れを使う事をメソッドの呼び出しと言います。
例えば、下の様な「paint()」の中で「文1」〜「文4」迄のまとまった処理を書く場合を考えます。

public void paint(Graphics g){
        :
        :
        文1;
        文2;
        文3;
        文4;
        :
        :
        :
}

上の様にズルズルと書いて終っても正しい結果は得られますが、其れを下の様にメソッドに定義してみましょう。

public void paint(Graphics g){
        :
        :
        method1(){
            文1;
            文2;
            文3;
            文4;
        }
        method1();
        :
        :
        :
}

「paint()」の中には「method1();」と言う1行だけで済み、処理のまとまりがはっきりします。
「paint()」は、上の@→A→Bの順に実行されます。
メソッドを使わなかった時と同じですね。
又、下の様に、同じ処理をもう1度行いたい時には、メソッド名を呼び出しさえすれば良いのです。

同じ処理をもう1度行いたい場合
public void paint(Graphics g){
        :
        :
        method1(){
            文1;
            文2;
            文3;
            文4;
        }
        method1();
        :
        :
        :
        method1(){
            文1;
            文2;
            文3;
            文4;
        }
        method1();
        :
        :
}
@→A→B→A→Cの順に実行

実際のプログラムは、以下の様にメソッドを並べて書きます。

例:
public class クラス名{
        :
public void paint(Graphics g){
        :
        :
        method1(){
        :
        :
        :
}
method1(){
        文1;
        文2;
        文3;
        文4;
        }
        :
}

此の様に、自分で作ったメソッドをユーザ定義メソッドと言います。

所属クラス

此迄の学習の中で、コンパイラが提供してくれたメソッドを利用していた時には、

g.drawLine(・・・);

の「g.」の様に、メソッド名の前にオブジェクト名を書いて、所属を明らかにしていました。
ユーザ定義メソッドでは、どのクラスに所属する事になるのでしょうか?
ユーザ定義メソッドは、其のクラスが書かれているクラスに所属します。
上で説明して来た例では、呼び出す「paint()」と呼び出されるユーザ定義メソッドとは、同じクラスの中に書いてあります。
所属が同じなので、メソッド名の前にわざわざクラスを表すオブジェクト名を書く必要が無いのです。


ユーザ定義メソッドの利用

メソッドの定義

メソッドがどの様な処理を行うかと言う、処理の本体を書く事をメソッドの定義と言います。
此処迄の学習でも「main()」や「paint()」を書いて来ました。
此がメソッドの定義です。
メソッドでは、呼び出し側に値を返す場合が有ります。
条件を利用してみようHouseLoop3.javaで利用したGraphicsクラスの「getColor」(色情報を返しました)やColorクラスの「equals」(「true」又は「false」を返しました)が、其れに当たります。
此の様にメソッドが返す値の型を、メソッドの型と言います。
Graphicsクラスの「drawLine」の様に呼び出し側に値を返さないメソッドには型は有りません。
型の無いメソッドをvoid型と言います。
メソッドの定義には、型名とメソッド名及び其のメソッドで行う処理(処理本体)を書きます。

型名 メソッド名(){
        処理本体
}
例: void dispMessage(){
if(param.equals("left")){
   System.out.println("message for you")
}

此の例は、MS-DOS画面に「message for you」と表示するメソッドです。
メソッド名は「dispMessage()」で、戻り値は無くvoid型です。

メソッドの呼び出し

メソッドを呼び出したい場所に「メソッド名()」を書きます。
メソッドの呼び出しは命令文なので、何れかのメソッドの中に書きます。

public クラス名{
       クラス変数の宣言

型名 メソッド名1(){
        :
        :
        メソッド名2();
        :
}

型名 メソッド名2(){
        :
        :
        :
        }
}

「クラス変数の宣言」は命令文では無く宣言文なので、クラスの内側で有ればメソッドの外側に書けます。
「メソッドの呼び出し」は命令文なので、メソッドの外側に書けません。
呼ばれたメソッドの中で、又別のメソッドも呼び出せます。

引数

メソッドを呼び出した時、其の時の状況によって必要なデータを呼び出し側からメソッドに与える仕組みを引数と言います。
メソッド側では、必要なデータを受け取る為の変数を用意し、メソッドの定義の先頭で、メソッド名に続く「()」の中に型と共に宣言します。
呼び出し側では、メソッドに渡す具体的なデータをメソッド名に続く「()」の中に書きます。
引数は複数有っても良く、「,」で区切って並べて書きます。
此の場合、呼び出し側で指定したデータは、順番にメソッド側で用意された変数にコピーされます。
メソッド側で用意された変数を仮引数、呼び出し側から渡されるデータを実引数と言います。

メソッド側
型 メソッド名(型 仮引数1, 型 仮引数2, ・・・){

}
呼び出し側
メソッド名(実引数1, 実引数2, ・・・);

メソッド側の仮引数は、呼び出し側からのデータで初期化される事を除いては、メソッド内で宣言されたローカル変数と全く同じ様に扱えます。
しかし、仮引数はメソッドのローカル変数の為、呼び出し側で仮引数名を使えません。
呼び出し側からデータを仮引数に渡すチャンスは唯1度、メソッドを呼び出す時に実引数に書く事です。
実引数には、変数名も書けます。
其の場合は、其の変数に記録されているデータがメソッド側の仮引数に渡されます。
呼び出し側、メソッド側の双方に変数「x」がありますが、それぞれローカル変数であり、全く別の物です。
両者の型が一致している事が重要なのです。
引数にオブジェクト名が指定されている時は、オブジェクト名を指すアドレスがメソッド側にコピーされます。

return文

メソッドは、呼び出し側に1つだけ値を返せます。
メソッドでどの値を返すのかを明確に示し、制御を呼び出し側に戻すのが「return文」です。
return文は制御を呼び出し側に戻す、いわば「出口」です。
1つのメソッドの中に複数のreturn文も書けます。
しかし、複数の出口を持つメソッドは構造化プログラミングに違反する為、余り勧められません。
return文は通常、メソッドの最後に次の様に書きます。

return 式;

「式」で求められる値が呼び出し側に返されます。
「式」の型と「メソッドの型」は同じでなければなりません。

例: int add(int x, int y){
   int z

   z = x+y;
   return z;
}
int add(int x, int y){
   return x+y;
}

戻り値の受け取り

メソッド側から返された値を呼び出し側で受け取る時は、メソッドの呼び出し全体を1つの変数やオブジェクトの様に扱います。

戻り値を代入する例
呼び出し側 メソッド側
        :
        :
int x = method(0, 20);
        :
        :
int method(int x, int y){
        int z;
        :
        :
        return z;
}
@は、「呼び出し側」から「method」を呼び出します。
実引数「0」が仮引数「x」に、実引数「20」は仮引数「y」に代入されてメソッドを実行します。
Aは、実行の結果、ローカル変数「z」に求められたint型の値を「呼び出し側」に返します。
呼び出し側では、此の値を「x」に代入します。
戻り値を他のメソッドの引数として利用する例
呼び出し側 メソッド側
        :
        :
method2(method1(10, 20));
        :
        :
int method(int x, int y){
        int z;
        :
        :
        return z;
}
void method2(int x){
        :
}
@は、「呼び出し側」から「method1」を呼び出します。
実引数「10」が仮引数「x」に、実引数「20」が仮引数「y」に代入され、メソッドを実行します。
Aは、実行の結果、ローカル変数「z」に求められたint型の値を「呼び出し側」に返します。
Bの「呼び出し側」は、此の値を実引数として「method2」を呼び出し、此の値は仮引数「x」に代入され、「method2」が実行されます。
戻り値を式の中で利用している例
呼び出し側 メソッド側
        :
if(method(10)){
        :
}
else{
        :
}
        :
        :
boolean method(int x){
        boolean flag;
        :
        return flag;
}
@は、「呼び出し側」から「method」を呼び出し、実引数「10」が仮引数「x」に代入されます。
Aは、実行の結果、boolean型のローカル変数「flag」に求められた結果を呼び出し側に返します。
呼び出し側では、此の結果でif文の選択の判断をします。

MedamaS3.javaでは、28行目でメソッドの結果を変数「flag」に代入しています。
しかし、以下の様に直接if文の条件にも書けます。

if文の例
for(int i = 0;i < draw.length;i++){
        if(!drawshap(g,x[i], y[i], w[i], h[i], draw[i])){
                g.drawString("データ"+i+"エラー", 40, 160);
        }
}
ソース ダウンロード
MedamaS2.java Medama04.zip MedamaS2.html
MedamaS3.java MedamaS3.html

戻る