演習: クラスとインスタンス
前半(1-A〜1-G)は本文の構文と典型的なつまずきを扱います。後半(1-H〜1-J)は複数フィールドのクラスにメソッドや状態変更を組み込みます。各問題ごとに新しい .java ファイルでクラスを定義し、Main.java の main メソッドから動作確認します。
1-A. Counter の定義
Section titled “1-A. Counter の定義”カウンターを表す Counter クラスを Counter.java に定義してください。次のとおり定義します。
- フィールド:
count(int) - コンストラクターで初期値を受け取って初期化する
getCount(): 現在のcountを返す
Counter c = new Counter(0);System.out.println(c.getCount());出力例:
0ヒント
コンストラクターはクラス名と同じ名前で定義し、引数で受け取った値を this.count = count; のようにフィールドへ代入します。getCount() は引数なしで int を返すメソッドで、return count; でフィールドの値を返します。
1-B. Counter に increment を追加
Section titled “1-B. Counter に increment を追加”Counter に increment() メソッドを追加してください。count を 1 増やす状態変更のメソッドで、戻り値はありません(void)。
Counter c = new Counter(0);c.increment();c.increment();c.increment();System.out.println(c.getCount());出力例:
3ヒント
void メソッドは return 文が不要です。count = count + 1; または count++; で値を 1 増やせます。メソッドの中ではフィールドに直接アクセスできます。
1-C. Point の定義
Section titled “1-C. Point の定義”座標を表す Point クラスを定義してください。次のとおり定義します。
- フィールド:
x(int)、y(int) - コンストラクターで両方の値を受け取って初期化する
show():(x, y)の形式で出力
Point p = new Point(3, 5);p.show();出力例:
(3, 5)ヒント
引数 2 つのコンストラクターは public Point(int x, int y) の形式です。フィールドと引数の名前が同じなので、this.x = x; のように this. を使います。show() は (、x の値、, 、y の値、) を文字列連結で組み立てます。
1-D. Point に distanceFrom を追加
Section titled “1-D. Point に distanceFrom を追加”Point に distanceFrom(Point other) メソッドを追加してください。他の Point を受け取って、その点までの距離を double で返します。2 点間の距離は √((x₁ - x₂)² + (y₁ - y₂)²) です。
Point a = new Point(0, 0);Point b = new Point(3, 4);System.out.println(a.distanceFrom(b));出力例:
5.0ヒント
引数の型は Point。メソッドの中では自分のフィールド x、y と、引数のフィールド other.x、other.y を使い分けます。平方根は Math.sqrt(...) で求められます。
1-E. Person の定義
Section titled “1-E. Person の定義”人を表す Person クラスを定義してください。次のとおり定義します。
- フィールド:
name(String)、age(int) - コンストラクターで両方の値を受け取って初期化する
introduce():私は田中、25歳ですのような自己紹介文を出力
Person p = new Person("田中", 25);p.introduce();出力例:
私は田中、25歳ですヒント
コンストラクターで this.name = name; this.age = age; のようにフィールドへ代入します。introduce() は戻り値なし(void)のメソッドで、System.out.println("私は" + name + "、" + age + "歳です"); のように文字列連結で出力します。
1-F. Person に birthday を追加
Section titled “1-F. Person に birthday を追加”Person に birthday() メソッドを追加してください。age を 1 増やします。誕生日を迎えるたびに呼び出します。
Person p = new Person("田中", 25);p.introduce();p.birthday();p.introduce();出力例:
私は田中、25歳です私は田中、26歳ですヒント
1-B の Counter.increment と同じパターンです。void メソッドで age = age + 1; または age++; を書きます。
1-G. this 書き忘れの出力予測
Section titled “1-G. this 書き忘れの出力予測”次のコードを実行すると何が出力されるかを、コンパイルする前に予測してください。予測したあとで実際にコンパイル・実行し、結果を確認します。
public class Sample { String name;
public Sample(String name) { name = name; }}Sample s = new Sample("田中");System.out.println(s.name);ヒント
本文 this キーワード の警告ボックスを参照してください。フィールドと引数の名前が同じ場合、this. を書かないとフィールドには代入されません。コンストラクターの中の name = name; は、引数 name に引数 name を代入しているだけで、フィールドの name は初期値の null のまま残ります。
1-H. Book の定義と sell メソッド
Section titled “1-H. Book の定義と sell メソッド”書籍を表す Book クラスを定義してください。次のとおり定義します。
- フィールド:
title(String)、price(int)、stock(int) - コンストラクターで 3 つの値を受け取って初期化する
show(): 書名・価格・在庫をこころ: 650円 (在庫 3)の形式で出力sell(int quantity): 在庫をquantity冊販売する状態変更メソッド。quantityは 1 以上の値を想定するquantityが現在のstock以下なら、stockをquantity分減らして『書名』を quantity 冊販売しましたを出力quantityがstockより多いなら、『書名』は在庫不足です(在庫 stock、要求 quantity)を出力して在庫を変えない
Book b = new Book("こころ", 650, 3);b.show();
b.sell(2);b.show();
b.sell(5);b.show();出力例:
こころ: 650円 (在庫 3)『こころ』を2冊販売しましたこころ: 650円 (在庫 1)『こころ』は在庫不足です(在庫 1、要求 5)こころ: 650円 (在庫 1)ヒント
sell は 1-B の Counter.increment と同じく状態を変更するメソッドですが、引数を受け取り、条件によって振る舞いが変わります。if で quantity <= stock を判定して、成立する場合だけ stock -= quantity; を実行します。
メソッドの中ではフィールド title も stock も直接参照できます。Book は後の章の統合演習でも登場します。
1-I. Book 配列から在庫切れを抽出
Section titled “1-I. Book 配列から在庫切れを抽出”Main.java で 4 冊分の Book インスタンスを配列で作り、在庫が 0 の本のタイトルだけを出力してください。
Book[] books = { new Book("こころ", 650, 3), new Book("吾輩は猫である", 780, 0), new Book("ノルウェイの森", 680, 5), new Book("人間失格", 590, 0),};
// ここで在庫が 0 の本のタイトルを出力する出力例:
吾輩は猫である人間失格ヒント
Book にフィールド stock を読むメソッド(getStock())と title を読むメソッド(getTitle())を追加してから利用するか、books[i].stock のように直接アクセスしても構いません。拡張 for 文 for (Book b : books) で配列を走査し、if で在庫が 0 の本だけを出力します。
1-J. Person リストの平均年齢
Section titled “1-J. Person リストの平均年齢”Main.java で複数の Person インスタンスを List<Person> に入れて、全員の平均年齢を出力してください。
import java.util.ArrayList;import java.util.List;
List<Person> people = new ArrayList<>();people.add(new Person("田中", 25));people.add(new Person("鈴木", 32));people.add(new Person("佐藤", 28));people.add(new Person("中村", 41));
double average = 0;// ここで average に平均年齢を代入する
System.out.println("平均年齢: " + average);出力例:
平均年齢: 31.5ヒント
Java 基礎の 合計と平均 と同じパターンを Person のリストに適用します。拡張 for 文 for (Person p : people) で各要素を取り出し、age フィールドを合計します。平均は double で出力するので、(double) sum / people.size() のように片方を double にキャストします。