プログラミング基礎I(再) 山元進
Lesson 8 の一部 クラスとは クラスの宣言 オブジェクトの作成 クラスのメンバー メソッドとは メソッドの引数、戻り値 フィールド→変数・配列 メソッド メソッドとは メソッドの引数、戻り値
クラスとは 変数の型を拡張したもの プログラムで使う部品の仕様書 例えば車のデータベース 車のメーカー、車種、登録番号などのデータ データベースの操作 (新規データのボタンなど) プログラムで使う部品の仕様書 そのクラスのオブジェクトを作ると初めて部品になる 「継承」などの仕組みにより、カスタマイズが安全、簡単にできる → プログラミング基礎IIで学習
クラスを宣言する(p. 217) プログラム コードの中で、クラスを定義する部分をクラスの宣言(declaration) と呼ぶ クラス中にはメンバがある メンバにはフィールドとメソッドがある フィールドは、対象の性質を表す変数 メソッドは、対象の機能を表すコード クラスの宣言は各メンバの宣言の集まり クラス内でクラスを宣言することも可能
クラスの宣言の構造 class クラス名 { 型名 フィールド名; … 戻り値の型 メソッド名 (引数リスト) 文; return 式; }
クラスの宣言の例 class Car { int num; double gas; } この例は、フィールドだけをもつクラスの宣言
オブジェクトの作成 クラスの宣言は、プログラムで使う部品のひな形(仕様書と思っても良い) 実際に使うためには、部品を製造する必要あり 作った部品 = オブジェクト, インスタンス オブジェクト作成の方法 変数 = new クラス名(); 例 Car car1; // car1 は Car クラスのオブジェクト car1 = new Car(); // car1 : 固有名詞のようなもの
メンバにアクセスする フィールドにアクセス フィールドは変数なので、前にオブジェクト名がついても、やはり変数として扱われる オブジェクトと結びつけられた変数名.フィールド名 例 car1.num, car1.gas フィールドは変数なので、前にオブジェクト名がついても、やはり変数として扱われる 代入などができる(教科書 p.224, 図8-5 参照)
クラスの利用(p. 225) // 車クラス class Car { int num; double gas; } class Sample1 public static void main(String args[]) Car car1; // 同じファイルで定義したクラスは(import せずに)使っても良い car1 = new Car(); car1.num = 1234; car1.gas = 20.5; System.out.println("車のナンバーは" + car1.num + "です。"); System.out.println("ガソリン量は" + car1.gas + "です。");
補足 2つ以上オブジェクトを作成しても良い Car car1; car1 = new Car(); // Car object を作って car1 と命名 car1.num = 1234; car1.gas = 20.5; Car car2; car2 = new Car(); car2.num = 2345; car2.gas = 30.5;
メソッドを定義する メソッド : クラスのメンバの一種 オブジェクトに作用して様々な機能を実現する 引数をとり、何か値を返すのが基本 例 戻り値の型 メソッド名(引数リスト) // ここの引数リストに書かれるのは仮引数 { 文; ・・・ return 式; // 呼び出し元に返す値を指定する }
void 型 void n. 空間; 空所, 割れ目; 空虚(感). メンバが値を返さない時は void 型にする 三省堂提供「EXCEED 英和辞典」より メンバが値を返さない時は void 型にする void メソッド名(引数リスト) { 文; ・・・ }
メソッドを呼び出す // 車クラス class Car { int num; double gas; void show() // 車オブジェクトの ナンバー と ガソリンの量を標準出力に印字する System.out.println("車のナンバーは" + num + "です。"); // クラス内でメンバを利用する時は、メンバ名だけで System.out.println("ガソリン量は" + gas + "です。"); // アクセスできる。 } class Sample2 public static void main(String args[]) Car car1; car1 = new Car(); car1.num = 1234; car1.gas = 20.5; car1.show();
// 車クラスの中で車クラスのメソッドを呼び出す class Car { int num; double gas; void show() System.out.println("車のナンバーは" + num + "です。"); System.out.println("ガソリン量は" + gas + "です。"); } void showCar() System.out.println("これから車の情報を表示します。"); show(); class Sample3 public static void main(String args[]) Car car1; car1 = new Car(); car1.num = 1234; car1.gas = 20.5; car1.showCar();
メソッドの引数 例えば、ナンバーを設定するメソッドでは、設定すべき番号を伝えてやる必要がある。必要な情報をメソッドに渡してやるのが引数 メソッドの定義に使うのは仮引数 実際にどんなものが渡されるかは分からないが、名前がないと呼ぶのに困るので、仮名をつける メソッドを呼出し時に実際に渡すのが実引数
// 車クラス class Car { int num; double gas; void setNum(int n) // n は仮引数 num = n; System.out.println("ナンバーを" + num + "にしました。"); } void setGas(double g) gas = g; System.out.println("ガソリン量を" + gas + "にしました。"); void show() System.out.println("車のナンバーは" + num + "です。"); System.out.println("ガソリン量は" + gas + "です。"); class Sample4 public static void main(String args[]) Car car1 = new Car(); car1.setNum(1234); // 1234 は実引数。必要に応じてどんな値にしても良いし、変数にしても良い。 car1.setGas(20.5); メソッドの引数
補足 変数を実引数にする場合に、仮引数と名前が違っても良い。 ただし、型が同じである必要がある。 例 class Sample4 { public static void main(String args[]) int number = 1234; double gasoline = 20.5; Car car1 = new Car(); car1.setNum(number); car1.setGas(gasoline); }
補足(this) クラスの宣言の中では、メンバの前に何も指定しなくてもアクセスできる そのメンバがフィールドでもメソッドでも メソッドの定義中、呼び出される際のオブジェクト名の代わりに this というキーワードが使える 例 Sample4.java の setGas() の定義を以下の様にしても良い。 void setGas(double gas) { this.gas = gas; System.out.println("ガソリン量を" + this.gas + "にしました。"); }
メソッドの引数(複数の場合) // 車クラス class Car { int num; double gas; void setNumGas(int n, double g) num = n; gas = g; System.out.println("車のナンバーを" + num + "にガソリン量を" + gas + "にしました。"); } void show() System.out.println("車のナンバーは" + num + "です。"); System.out.println("ガソリン量は" + gas + "です。"); class Sample5 public static void main(String args[]) Car car1 = new Car(); int number = 1234; double gasoline = 20.5; car1.setNumGas(number, gasoline);
メソッドの戻り値 メソッドの呼び出し元に戻す(返す)情報 例えば車のナンバーを取得するメソッド サンプルコードは次項 エラー発生の通知、演算の結果、などなど 例えば車のナンバーを取得するメソッド ナンバーは int 型だから、int 型の値を返すようにするのが自然に思える サンプルコードは次項
戻り値を持つメソッドの呼び出し // 車クラス class Car { int num; double gas; int getNum() // int 型のナンバーを返すという宣言 System.out.println("ナンバーを調べました。"); return num; // 返す値を決める } double getGas() System.out.println("ガソリン量を調べました。"); return gas; void setNumGas(int n, double g) num = n; gas = g; System.out.println("車のナンバーを" + num + "にガソリン量を" + gas + "にしました。"); void show() { System.out.println("車のナンバーは" + num + "です。"); System.out.println("ガソリン量は" + gas + "です。"); } class Sample6 public static void main(String args[]) Car car1 = new Car(); car1.setNumGas(1234, 20.5); int number = car1.getNum(); double gasoline = car1.getGas(); System.out.println("サンプルから車を調べたところ"); System.out.println("ナンバーは" + number + "ガソリン量は" + gasoline + "でした。");
補足 戻り値は一つしか無い 呼び出し元では、戻り値を使わないで無視することもできる 使う場合 使わない int number = car1.getNum(); // number に戻り値を保存 使わない car1.getNum(); // 戻り値は無視。何処にも保存されない。
クラスの設計 プログラムを設計するのに、扱う対象を分析して記述するとうまく行くようだ → Object 指向 対象の性質 : コンピュータ上ではデータ 対象が持つ機能 : データに対する操作 両者を合わせて定義するものがクラス 車のデータベースの例(教科書 p216, 図8-1) ナンバー、ガソリン量 → データ (フィールド) ナンバー設定、ガソリン増減 → 操作(メソッド)
演習課題1 main メソッドを持つ class Report1 中に、int num を仮引数とし、 int 型の戻り値として num の桁数を返すメソッド ketasuu を実装せよ。また、main メソッドでは、キーボードから0以上の整数を読み取り int iNum に代入せよ。さらに、iNum を実引数として ketasuu を呼び出し、戻り値を画面上に印字せよ。 ただし、ketasuuは static である必要があるので、 static int ketasuu(int num) と宣言せよ
演習課題2 main メソッドを持つ class Report2 中に、int num を仮引数とし、 boolean 型の戻り値としてnum が素数であるかどうかを 返すメソッド sosuu を実装せよ。また、main メソッドで101 から 110 の整数を実引数としてsosuu メソッドを呼び出し、それぞれの整数が素数であるか否かを書き出せ。 ただし、sosuuは static である必要があるので、 static boolean sosuu(int num) と宣言せよ
演習問題3(次のページに続く) main メソッドを持つ Report3 クラスと同じファイル中に、次の仕様を満たす Student クラスを作成せよ。 以下の各フィールドを持つ String name; String id; int mark; // mark : 点数のこと 以下のメソッドを持つ boolean passed() mark >= 80 で true, それ以外で false String info() name, id, mark をタブで区切った文字列を返す
演習問題3(前のページからの続き) main メソッド中に、Student クラスの変数 student を作成し、name に自分の名前、id に自分の学籍番号、mark に中間試験の予想点数(各人が勝手に決めて良い)を入れよ。 main メソッド中で、student.info(), student.passed() の戻り値を画面に印字せよ。