| 目次| 1234567891011121314
| 資料| 予定| 課題| 宿題|

メソッドとは何か?

これまで出てきた System.out.println や KeyboardInput.askIntなどをメソッ ドと言う.メソッドとはオブジェクトの中のデータを操作するときの命令(操 作手順)を提供するものである.
  int n = KeyboardInput.askInt("?");
  
このメソッドは,整数を入力するためのものである.つまり上記の文では,文 字列 "?" を表示し,キーボードから入力された数値を変数 n に代入する,と いう処理を行っている.このとき,メソッドに渡される文字列 "?" を引数と 言い,メソッドから戻ってくる整数を戻り値と言う.さらに,上記の文のよう にメソッドに処理をしてもらうことを,メソッドの呼び出しと言う.
  double d = 10.0;
  System.out.println(d);
  
という文では,引数は double 型の変数 d で,戻り値は無視されている.と いうのも,System.out.println というメソッドで重要なのは,与えた引数を (標準出力に)表示することだからである.また,
  String line = line.toLowerCase();
  
という文では,toLowerCase メソッドを呼び出して,その戻り値を変数 line に代入している.この呼び出しでは引数はない(引数は 0 個).

メソッドを定義する

既に述べたように,メソッドはオブジェクトの中のデータを操作するときの命 令(操作手順)を提供する.そしてこれまで,そのようなメソッドをいくつか プログラムの中で利用してきた.つまり「メソッドの呼び出し」ばかりをやっ てきた.ここでは,自分で「メソッドの作成」を行ってみよう(まず,ここで はメソッドがどんなものかイメージをつかみ,簡単な static メソッドを自分 で作成=定義できるようになれば良い).

いま,2つの整数の和を求めるプログラムを書いてみよう.

  public class Sum {
     public static void main(String[] args) {
        int a, b, sum;

        a = KeyboardInput.askInt("1 つ目の整数を入力して下さい:");
        b = KeyboardInput.askInt("2 つ目の整数を入力して下さい:");

        sum = a + b;

        System.out.println("2 つの整数の和は " + sum);
     }
  }
  
上のプログラムで一番重要なのは,10 行目である.ここで「2 つの整数の和」 を計算しているわけで,"System.out.println"が"表示する"などと同じように これを一つのまとまった処理として捉えることも可能である.つまり 「2 つの整数の和の計算」の部分を Java 言語のメソッドとして定義する(表 現する)ことが可能である.そのように上のプログラムを書き替えるものが下 のプログラムである.
  public class Sum2 {
     public static void main(String[] args) {
        int a, b, sum;

        a = KeyboardInput.askInt("1 つ目の整数を入力して下さい:");
        b = KeyboardInput.askInt("2 つ目の整数を入力して下さい:");

        sum = add(a, b);
        System.out.println("2 つの整数の和は " + sum);
     }

     public static int add(int x, int y) {   
        int wa;

        wa = x + y;
        return wa;
     }
  }
  
これら 2 つのプログラムは全く同じ動作をする.Sum2 というクラス宣言の大枠は, となる.また,main メソッドの宣言の中身を見てみると, となる.さらに,add メソッドの宣言の中身を見てみると, となる.これを簡単に図示すると以下のようになる.
     公開されているメソッドである(アクセス制御)
     |     クラスメソッドである
     |     |    戻り値は int 型
     |     |    |  メソッドの名前は add
     |     |    |  |      引数は int 型で,名前は x と y
     ↓     ↓    ↓  ↓      ↓
   public static int add(int x, int y) {   
         …          ← メソッドの中身
      return wa;     ← 戻り値を表す return 文
   }
}
main メソッドの中で add メソッドを呼び出すと(9行目),main メソッドの 変数 a の値が add メソッドの変数 x に,main メソッドの変数 b の値が add メソッドの変数 y に代入される.そして add メソッド内で和の計算をし て,それを戻り値として main メソッドに戻る.その戻り値が main メソッド の変数 sum に代入される.ここで add メソッド内の変数 a, b, wa のスコー プはこの add メソッド内のみである.このように局所的に有効な変数を局所 変数またはローカル変数と言う. 最後に,メソッドの形式をまとめておく(なお,クラスの名前には名詞を,メ ソッドの名前には動詞を使うことが多い).
  [修飾子] 戻り値の型 メソッド名 (引数列) {
     ローカル変数
     メソッドの本体(処理)
     return 文                                ← 戻り値がある場合のみ
  }
  

戻り値のないメソッド

  public class GraphAsterisk {
     public static void main(String[] args) {
        printAsterisk(10);
     }
     public static void printAsterisk(int n) {   
        for (int i = 0; i < n; i++) {
           System.out.print("*");
        }
        System.out.println("");
     }
  }
  
上のプログラムは,ある数だけ星印を横に並べて表示する.ある整数を引数と して受けとり,その数だけ星印を横に表示しているのは,printAsterisk メソッ ドである.このように printAsterisk メソッドは星印を表示するためだけの もので,add メソッドのように値を計算するためのものではない.従って,こ の場合には戻り値が必要ない.このように戻り値のないメソッドを作る場合に は,戻り値の型として void を指定すれば良い.void は「空の」を意味する 英単語であり,void 型は int や double などと同様に「基本型」の一つであ る.

クラス

いままで,変数・配列・制御構造など,さまざまなJavaの機能について学んで きた.先週行ったように,これらの機能を使うといろいろなプログラムを自由 に作成できる.配列では,同じ変数の箱をまとめて扱う方法を学んだが,今回は 成績が学籍番号と点数でまとめられように現実に存在する「モノ」の概念に 着目し,プログラムを効率よく記述する方法を説明します.

クラスとは

現実に存在する「モノ」をひとまとめにして扱うためにクラスと言う考え方が 使われるようになっています.これまで記述してきたコードにもクラスはすで に使われています.
public class Hello {
    public static void main(String args[]) {
        System.out.println("こんにちは.");
        System.out.println("Hello,\n Java!");
    }
}
このプログラムでは,一番外側の({}で囲まれた)ブロックで"Hello"というク ラスを定義しています.このように先頭に"class"というキーワードで囲まれ たコードをクラスといいます.これまでのプログラムでは全体が1つのクラスに なっていましたが,今回は,これに加えてもう一つクラスを作成します.

クラスの仕組み

クラスとはプログラムの中では,classと言うキーワードと対応するブロックとして 表されますが,具体的には現実に存在する「モノ」を表現します.たとえば,「車」 と言うモノに着目してプログラムを作ります.

まず,「車」に関するデータとして次のようなものが考えられます.

  1. ナンバー
  2. ガソリンの残量
これらは,その時々の車の状態を表すため,「性質」のようなものとも考えら れます.また,車には次のような「機能」があると考えられます.
  1. ナンバーを決める
  2. ガソリンを入れる
  3. ナンバー・ガソリン量を表示する.
クラスとは,このような「モノ」の性質や,それに関わる機能をまとめながら, プログラムを作成していくために考えられました.クラスをまとめるにはおお ざっぱに書くと次のようなコードを記述します.
//車クラス
class 車
{
	ナンバー;
	ガソリン量;

	ナンバーを決める機能 ...
	ガソリンを入れる機能 ...
	ナンバーとガソリン量を表示する機能 ...
}

クラスを宣言する

今まで作ったプログラムはすべて public class クラス名 で始まっていた が,Java のプログラムはすべてクラスからできており,クラスを宣言するこ となしに Java プログラムを組むことはできない.(半分復習を兼ねて)クラ ス宣言の一般形式を書くと,
[修飾子] class クラス名 {
   //フィールドの宣言
   型 フィールド名;
   ......

   //メソッドの宣言
   戻り値の型 メソッド名(引数のリスト) {
      文;
      ...
      return 式;
   }
   ......
}
である.class は Java の予約語で,クラス宣言の開始を示す.クラス名は大 文字で始まる名詞とするのが「慣習」となっている.{ と } の間がクラス宣 言の内容であり,そのクラスがもつフィールドとメソッドが書かれる.フィー ルドとはクラスの性質を表し,「情報を保持する場所」でいわば変数のような ものである.,メソッドとはクラスの機能を表し,「情報を処理する方法」で いわば関数のようなものである. メソッドについては,後で追加するのでまず「性質」を表すフィールドを取り 扱います.まず,簡単なコードとして車のナンバーとガソリン量を格納する フィールドを持つ「Car(車)」と言うクラスを宣言します.
class Car {
     // ナンバー
     int num;

     //ガソリン量
     double gas;
}

クラスを利用する

上のようにするとクラスを宣言できます.しかし,宣言しただけでは不十分で す.実際のナンバーや,ガソリン量を記述していません.ここで「オブジェク トの作成」と言う作業が必要になります.「オブジェクトの作成」とは, 「実際に1台の車を作る」と言うイメージです.上の宣言の中で「車」 という「モノ」の性質と機能をまとめてクラスを宣言しましたが,次に実際に コード上で1台ずつ車を作成していきます.その後1台1台正しいナンバー・ ガソリン量を持つように設定します.コード上で作成されるこの車1台ずつの ことをオブジェクトといいます.Car クラスの宣言を利用して作成するオブジェ クトは,Carクラスのオブジェクトと呼びます.

それでは,コード上でオブジェクトを作成する記述を行います.そのためには

  1. オブジェクトを扱う変数を宣言する.
  2. オブジェクトを作成し,その変数で扱えるようにする.
2段階の記述が必要です.はじめの作業は,「宣言したクラスを使って, オブジェクトを扱う変数を宣言する.」ことです.これは,今まで int 型やdouble 型の変数を宣言した場合と同じように Car型を宣言します.
Car car1;
これでCar型の変数 "car1"が宣言されました.次に2の作業ですが,こちらは 配列で行ったように new演算子を使って Car型のオブジェクトをメモリ上に確 保します.
car1 = new Car();
この文により「newを使った結果を変数car1に代入」する事を行います. この代入により,「car1と言う変数を使って,今作成したCarクラスのオブ ジェクトを扱う」事ができるようになります.

以上をまとめると,

//車クラス
class Car {
    int num;
    double gas;
}

public class CarSample1 {
    public static void main(String[] args) {
	//Car 型の変数を宣言
	Car car1;

	//Carクラスのオブジェクトを作成・代入
	car1 = new Car();
    }
}
となります.

メンバにアクセスする

これでCarクラスのオブジェクトが作成されましたから,「車1台のナン バー・ガソリン量の実際の値を決める」ことができます.作成したオブジェ クトは"num","gas"と言うフィールドを持っていますので,そのフィールドに 実際の値を代入します.各フィールドにアクセスするには,作成したオブジェ クトを扱うクラス変数(car1)を使って
car1.num
car1.gas
のように,変数名に"."をつけてどのフィールドを対象にするか指定します.つまり car1のナンバーを"1234"とし,ガソリン量を20.5とするには,
//車クラス
class Car {
    int num;
    double gas;
}

public class CarSample2 {
    public static void main(String[] args) {
	//Car 型の変数を宣言
	Car car1;

	//Carクラスのオブジェクトを作成・代入
	car1 = new Car();

	car1.num = 1234;
	car1.gas = 20.5;
    }
}

クラスを使ったプログラム

では,以上をまとめた「車を管理する簡単なプログラム」を示します.
//車クラス
class Car {
    int num;
    double gas;
}

public class CarSample3 {
    public static void main(String[] args) {
	//Car 型の変数を宣言
	Car car1;

	//Carクラスのオブジェクトを作成・代入
	car1 = new Car();

	car1.num = 1234;
	car1.gas = 20.5;

	System.out.println("車のナンバーは "+ car1.num +" です.");
	System.out.println("ガソリン量は "+ car1.gas + " です.");
    }
}

クラスの配列

2つ以上のオブジェクトを扱うことももちろん可能です.変数 car1 の他に car2 を準備して new 演算子を利用しオブジェクトを対応させます.
	//Carクラスのオブジェクトを作成・代入
	car1 = new Car();

	car1.num = 1234;
	car1.gas = 20.5;

	car2 = new Car();

	car2.num = 3456;
	car2.gas = 32.5;
オブジェクトの配列を作成することもできます.
//車クラス
class Car {
    int num;
    double gas;
}

public class CarSample4 {
    public static void main(String[] args) {
	//Car 型の配列変数を宣言
	Car[] cars;

	//配列変数 cars にCar型変数2個を割当
	cars = new Car[2];

	//Carクラスのオブジェクトを2個作成・代入
	for(int i=0; i< cars.length ; i++) {
	    cars[i] = new Car();
	}

	cars[0].num = 1234;
	cars[0].gas = 20.5;

	cars[1].num = 3456;
	cars[1].gas = 32.5;

	for(int i=0 ; i<cars.length ; i++) {
	    System.out.print("車のナンバーは "+ cars[i].num +" で,");
	    System.out.println("ガソリン量は "+ cars[i].gas + " です.");
	}
    }
}

クラスとメソッド

今回のはじめでは,クラスが1個の場合でのメソッドについて説明した.クラ スの説明のところでも述べたようにクラスでは,「モノ」の「性質」の他に 「機能」も同時にまとめることができます.はじめでは,クラスが1個の場合に おけるメソッドの書き方・呼び出し方を説明しましたが,ここからは自分で書いた クラスにメソッドを追加し,他のクラスの中から呼び出す方法を説明します.

定義する

Carクラスにメソッドとして「車の情報を表示する機能」をまとめて記 述すると次のようになります.[この授業の範囲では,自分で用意するクラス の中で定義するメソッドに"public static"などの修飾子をつける必要はあ りません.]
class Car {
    int num;
    double gas;

    //車の情報を表示
    void show() {
        System.out.print("車のナンバーは "+ num +" で,");
        System.out.println("ガソリン量は "+ gas + " です.");
    }    
}

呼び出す

上のようにして定義したメソッドは,先ほど説明した「性質」を表すフィール ドと同様に
オブジェクトを指す変数名.メソッド名(引数リスト)
と書いて呼び出すことができます.
class Car {
    int num;
    double gas;

    //車の情報を表示
    void show() {
        System.out.print("車のナンバーは "+ num +" で,");
        System.out.println("ガソリン量は "+ gas + " です.");
    }    
}

public class CarSample5 {
    public static void main(String[] args) {
	//Car 型の変数を宣言
	Car car1;

	//Carクラスのオブジェクトを作成・代入
	car1 = new Car();

	car1.num = 1234;
	car1.gas = 20.5;

        //メソッドを呼び出します.
        car1.show();
    }
}

フィールドへのアクセス

main メソッドの中で作成したオブジェクトのフィールドにアクセスするには 次のように書きました.
    public static void main(String[] args) {
	//Car 型の変数を宣言
	Car car1;

	//Carクラスのオブジェクトを作成・代入
	car1 = new Car();

	car1.num = 1234;
	car1.gas = 20.5;
    }
クラスの宣言の中でフィールドにアクセスする場合は,
class Car {
    int num;
    double gas;

    //車の情報を表示
    void show() {
        System.out.print("車のナンバーは "+ num +" で,");
        System.out.println("ガソリン量は "+ gas + " です.");
    }    
}
のように書き,フィールドの前になにもつけないでアクセスします.この二つ に違いですが,前者では「変数 car1の指すオブジェクトのフィールド」 を指していましたが,後者では,「呼び出されたオブジェクト自分自身の フィールド」を指します.呼び出され方によって car1 オブジェクトの num フィールドを指したり,car2 オブジェクトの num フィールドを指すよ うになります.
class Car {
    int num;
    double gas;

    //車の情報を表示
    void show() {
        System.out.print("車のナンバーは "+ num +" で,");
        System.out.println("ガソリン量は "+ gas + " です.");
    }    
}

public class CarSample6 {
    public static void main(String[] args) {
	//Car 型の変数を宣言
	Car car1,car2;

	//Carクラスのオブジェクトを作成・代入
	car1 = new Car();

	car1.num = 1234;
	car1.gas = 20.5;

	car2 = new Car();

	car2.num = 3456;
	car2.gas = 32.5;

        //メソッドを呼び出します.
        car1.show();
        car2.show();
    }
}
[onisi@m449 ~/Java] java CarSample6
車のナンバーは 1234 で,ガソリン量は 20.5 です.
車のナンバーは 3456 で,ガソリン量は 32.5 です.

引数・戻り値のあるメソッド

上の例で追加したメソッドは,引数・戻り値のないメソッドでしたが, それらを含むメソッドも同様に作成・呼び出すことができます.
class Car {
    int num;
    double gas;

    //車の情報を表示
    void show() {
        System.out.print("車のナンバーは "+ num +" で,");
        System.out.println("ガソリン量は "+ gas + " です.");
    }

    //引数のあるメソッド
    void setNum(int n) {
	num = n ;
	System.out.println("ナンバーを "+num+" にしました.");
    }

    void setGas(double g) {
	gas = g ;
	System.out.println("ガソリン量を "+gas+" にしました.");
    }

    //戻り値・複数の引数を持つメソッド
    double calcNenpi(double tank, double dist) {
	return dist / ( tank - gas ) ;
    }
}

public class CarSample7 {
    public static void main(String[] args) {
	//Car 型の変数を宣言
	Car car1,car2;

	//Carクラスのオブジェクトを作成・代入
	car1 = new Car();

        //引数をつけてメソッドを呼び出します.
	car1.setNum(1234);
	car1.setGas(20.5);

        //メソッドを呼び出します.
        car1.show();

	//燃費を計算します
	//タンクの大きさは 50, 走行距離は 300
	double nenpi = car1.calcNenpi(50, 300);

	System.out.println("燃費は "+nenpi+" です");
    }
}
[onisi@m449 ~/Java] java CarSample7
ナンバーを 1234 にしました.
ガソリン量を 20.5 にしました.
車のナンバーは 1234 で,ガソリン量は 20.5 です.
燃費は 10.16949152542 です

課題


| 目次| 1234567891011121314
| 資料| 予定| 課題| 宿題|