まず、簡単な例で見ていきましょう。下のプログラムをみてください。
//Ex1.java
class X
{
void method(){
System.out.println("こんにちは。私はXのオブジェクトです。");
}
}
class Ex1
{
public static void main(String[] args){
X x = new X();
x.method();
}
}
上のプログラムでは、まずクラスXを定義し、そのメソッドとしてmethodを定義しています。メソッドと言ってもただ「こんにちは。私はXのオブジェクトです。」と画面に表示するだけのメソッドです。いつものように、頭にvoidがついていますね。
そして、クラスEx1のmainの中に「x.method();」と書いてありますが、ここでXのメソッドmethodを実行しているわけですね。
Fig.1 Ex1の実行
このようなプログラムはさんざん書いてきたので難しくはないですよね。まずは、小手調べです。
さて、ここで、上のプログラムを次のように変えてみます。
//Ex2.java
class X
{
int method(){
System.out.println("こんにちは。私はXのオブジェクトです。");
return 1;
}
}
class Ex2
{
public static void main(String[] args){
X x = new X();
x.method();
}
}
//Ex3.java
class X
{
int method(){
System.out.println("こんにちは。私はXのオブジェクトです。");
return 1;
}
}
class Ex3
{
public static void main(String[] args){
int d; //整数変数dの宣言(「整数dを使うよ」という意味)
X x = new X();
d = x.method();//考え込むと不思議な文ですが、次のような意味になります。
//まず、Xのmethodの中身が実行される。
//そして、このメソッドから返された値1がdに代入される。
System.out.println("methodから返された値="
+ d); //dの値の出力
}
}
ここで、「d = x.method();」は不思議な文ですが、これで、Xのmethodの中身がまず実行され、次に値1が返され、それがdに代入されることになるのです。ここでいう「返される」とは、実質的には、このメソッドx.methos()が実行されたあと、x.method()と書いてあるところが数値1に変わるということなのです。
実際実行してみてください。まず、画面に「こんにちは。私はXのオブジェクトです。」と出力され、その後に(と言っても,人間の目にその順序は見えませんが)数値1が画面に出力されて終わりになります。
Fig.2 Ex3の実行
Ex2.javaとEx3.javaの違いは、単に、返された値を使うか使わないかの違いです。このように返された値を使う使わないはプログラマの自由なのです。
上の例はあまりにも無意味な例だったので、Xに「二つの整数値を引数に取って、その合計を返す」メソッドをつくって、そのメソッドを使うプログラムを書いてみましょう。
//TasizanEx.java
import java.io.*;
class X
{
int add() throws IOException{
String s;
BufferedReader br =
new BufferedReader(new
InputStreamReader(System.in));
int a, b; //二つの整数をいれる変数
System.out.println("これから二つの整数の足し算をします。");
System.out.println("まず、ひとつめの整数を入力してください。");
s = br.readLine();
//sにユーザの入力文字列を格納
a = Integer.parseInt(s);
System.out.println("もうひとつの整数を入力してください。");
s = br.readLine();
//sにユーザの入力文字列を格納
b = Integer.parseInt(s);
//次のreturnで合計を返す
return a + b;
}
}
class TasizanEx
{
public static void main(String[] args) throws IOException{
X x = new X();
int d = x.add();//整数変数dが宣言され、すぐにx.add()が実行され、その返す値がdに代入される。
System.out.println("合計:"
+ d);
}
}
Fig.3 tasizan.exe
この例のように、返り値(戻り値)は定数である必要はないのです。
それでは、初心者には少し難しい問題をひとつ。できなくても大丈夫です。とても熱心な人は今までの復習をしながら考えてみてください。それほど熱心でもない普通の人は、ちょっと考えてから、答えを眺めてみてください。
問題:
入門5の犬を次のように改良したクラスをつくってください。
クラス 犬
データメンバ:名前
体力(整数)
コンストラクタ:名前を受け取り、はじめの体力を10とする
メンバメソッド :食事をもらう(もらってたべた量だけ体力を増やすメソッド)
鳴く(鳴いて、体力を5減らす)
ただし、メソッド「食事」と「鳴く」は実行後の体力を「返り値」で報告するものとします。
解答例:
class Inu
{
private String name;
private int tairyoku;
Inu(String s){
name = s;
tairyoku = 10;
}
int syokuji() throws IOException{
System.out.println(name + "に食事をさせます。どれだけ食べさせますか?);
String s;
BufferedReader br =
new BufferedReader(new
InputStreamReader(System.in));
int food = Integer.parseInt(s);
tairyoku += food;
return tairyoku; //tairyokuの値を返す
}
int naku(){
System.out.println("わん。僕は"
+ name + "だ。");
tairyoku -= 5;
return tairyoku; //tairyokuの値を返す
}
}
「tairyoku += food;」は「tairyokuにfoodを足せ」、「tairyoku
-= 5;」は「tairyokuから5引け」という意味でしたね。ポイントはsyokuji、nakuメソッドの前にintがあり、それらの定義の最後にはreturn文があるということです。
このクラスを使ったプログラム例は次のようなものでしょう。
//InuSample4.java
import java.io.*;
class Inu
{
private String name;
private int tairyoku;
Inu(String s){
name = s;
tairyoku = 10;
}
int syokuji() throws IOException{
System.out.println( name + "に食事をさせます。どれだけ食べさせますか?");
String s;
BufferedReader br =
new BufferedReader(new
InputStreamReader(System.in));
s = br.readLine();
int food = Integer.parseInt(s);
tairyoku += food;
return tairyoku; //tairyokuの値を返す
}
int naku(){
System.out.println("わん。僕は"
+ name + "だ。");
tairyoku -= 5;
return tairyoku; //tairyokuの値を返す
}
}
class InuSample4
{
public static void main(String[] args) throws IOException{
System.out.println("犬をメモリ上に生成します。名前を決めてください。");
String s;
BufferedReader br =
new BufferedReader(new
InputStreamReader(System.in));
s = br.readLine();
Inu kai_inu = new Inu(s); //飼い犬の生成 名はユーザがsに入力したもの
System.out.println(); //見やすさのための改行
for(int i = 0; i < 5 ;i++){ //5回だけメモリ上の犬と遊ぶプログラムです
System.out.println("どうします?");
System.out.println("1
食事を与える 2 鳴かす");
s =
br.readLine();
int ans =
Integer.parseInt(s);
if(ans == 1){
int t;
t =
kai_inu.syokuji(); //まず、Inuのsyokujiの内容が実行され、その結果の体力が
//Inuのsyokujiの返り値として与えられ、tに代入される。
System.out.println("犬の体力=" + t);
}
else if(ans == 2){
int t;
//上のtとは別の{ }ブロック内にあるので全く無関係
t = kai_inu.naku(); //まず、Inuのnakuの内容が実行され、その結果の体力が
//Inuのnakuの返り値として与えられ、tに代入される。
System.out.println("犬の体力=" + t);
if(t < 0){
System.out.println("食事が不十分だったので、犬はストライキをしてしまいました。");
break; //for文からぬけろという命令 体力が負になったらおしまいということです
} //if(t < 0)のかっこ閉じる
} //if(ans==2)のかっこ閉じる
System.out.println(); //見やすさのための改行
} //for(i=0;i<5;i++)のかっこ閉じる
System.out.println("おわり");
}
}
Fig.4 InuSample4の実行(育てゲーも夢じゃない?)
ところで、気が付いていましたか?プログラムの中心のmainもよく見ると、メソッドの定義と同じ形をしていますね。
class X
{
public static void main(){
...
}
}
実は、mainは、プログラムの中心を表わすメソッドなのです。そして、mainは「値を返さないメソッド」なので前にvoidがあるのです。一番前にあるpublicは、まだあまり詳しく説明していませんが「公開」などという意味でした。その次のstaticはまた後で説明しますので、今は、あまり気にしないでおいてください。とにかく、mainもメソッドなのです。