問題2-7
ロボットを表すRobotクラスを作成してください。
Robotクラスを使用するStaticBasicPracticeクラスのmainメソッドはすでに完成しています。
(変更は禁止です)
【Robotクラス】
次のような2つのインスタンスフィールドと、1つのクラスフィールドを持ちます。
・ロボットIDを表すインスタンスフィールド id (int型)
・ロボット名を表すインスタンスフィールド name (String型)
・ロボット総生産数を表すクラスフィールド total (int型)String型の引数をひとつだけ持つコンストラクタを定義します。
引数で渡ってきた文字列をロボット名に設定し、ロボット総生産数をインクリメントします。
ロボットIDは1からの連番を割り振りますが、ロボット総生産数の値をうまく利用してください。ロボット総生産数の値を取得するためのgetTotalクラスメソッド(引数なし・戻り値 int型)を定義します。
ロボットの情報を紹介するためのintroduceメソッド(引数なし・戻り値なし)を定義します。
実装は下記実行結果を参考にしてください。
【実行結果】
ロボット総生産数:0 ロボット総生産数:5 ロボット総生産数:6 ID:1 NAME:RX ID:2 NAME:PZ ID:3 NAME:SS ID:4 NAME:FG ID:5 NAME:VC ID:6 NAME:SUPER-Z
【StaticBasicPractice.java】
public class StaticBasicPractice { public static void main(String[] args) { // ロボット総生産数の表示 System.out.println("ロボット総生産数:" + Robot.getTotal()); // 5体のロボットオブジェクトを作成 // (6体目は保留) Robot[] robots = { new Robot("RX"), new Robot("PZ"), new Robot("SS"), new Robot("FG"), new Robot("VC"), null }; // ロボット総生産数の表示 System.out.println("ロボット総生産数:" + Robot.getTotal()); // 6体目のロボットオブジェクトを作成 robots[5] = new Robot("SUPER-Z"); // ロボット総生産数の取得 System.out.println("ロボット総生産数:" + Robot.getTotal()); System.out.println(); // 6体のロボットの情報を表示 for(int i = 0; i < robots.length; i++) { robots[i].introduce(); } } } // ここにRobotクラスを作成してください
解答例
【StaticBasicPractice.java】
public class StaticBasicPractice { public static void main(String[] args) { // ロボット総生産数の表示 System.out.println("ロボット総生産数:" + Robot.getTotal()); // 5体のロボットオブジェクトを作成 // (6体目は保留) Robot[] robots = { new Robot("RX"), new Robot("PZ"), new Robot("SS"), new Robot("FG"), new Robot("VC"), null }; // ロボット総生産数の表示 System.out.println("ロボット総生産数:" + Robot.getTotal()); // 6体目のロボットオブジェクトを作成 robots[5] = new Robot("SUPER-Z"); // ロボット総生産数の取得 System.out.println("ロボット総生産数:" + Robot.getTotal()); System.out.println(); // 6体のロボットの情報を表示 for(int i = 0; i < robots.length; i++) { robots[i].introduce(); } } } // ロボットクラス class Robot { // ロボットID private int id; // ロボット名 private String name; // ロボット総生産数 private static int total; // コンストラクタ public Robot(String name) { this.name = name; // 総生産数をインクリメントし、IDに設定する total++; this.id = total; } // ロボット総生産数の取得 public static int getTotal() { return total; } // ロボット紹介 public void introduce() { System.out.println("ID:" + id + " NAME:" + name); } }
解説
クラスのメンバである「フィールド」と「メソッド」には、それぞれ2種類あります。
今回のテーマである「static」というキーワードを付けた「クラスフィールド」と「クラスメソッド」、そして「static」が付かない「インスタンスフィールド」と「インスタンスメソッド」です。
「staticの理解」はJavaを習得する上で壁となる1つです。
しっかり落ち着いて理解していきましょう。
まず最初の認識として、staticキーワードの付くクラスフィールド・クラスメソッドは特殊なものと考えてください。
staticキーワードの付かないインスタンスフィールド・インスタンスメソッドは、つまり「インスタンスごとのフィールド・メソッド」ということです。
たとえば日本人というクラスがあって、そのクラスからインスタンスを2つ作りました。
1つは山田さん、28歳、男性。
もう1つは鈴木さん、35歳、女性としましょう。
氏名も年齢も性別も、インスタンスごとに異なる値を取るわけですから、日本人クラスの氏名・年齢・性別フィールドは「インスタンスフィールド」というわけです。
そして日本人クラスには「名乗る」というメソッドがあるとすると、1つ目のインスタンスの「名乗る」メソッドは「私は山田です」と出力し、2つ目のインスタンスの「名乗る」メソッドは「私は鈴木です」と出力します。
インスタンスごとに異なる振る舞いをするメソッドなので「インスタンスメソッド」というわけです。
では、staticキーワードの付くクラスフィールド・クラスメソッドとはどのようなものかと言うと、「クラスで共通のフィールド・メソッド」です。
日本人クラスには「首都名」「通貨名」というフィールドがあるとすると、その値はインスタンスに関係なく共通で「東京」と「円」です。
インスタンス数が1個だろうと100個だろうと、クラスフィールド・クラスメソッドはクラス共通でたった1つしかないと言うことです。
今回の問題はロボットクラスを作成しましたが、ロボットIDとロボット名は各ロボットごとに異なる値を取るのでstaticなしのインスタンスフィールドです。
そして、ロボットクラスからいくつインスタンスを生成したか、つまり総生産数はインスタンスごとに持つ必要のないクラス共通のデータなのでstaticありのクラスフィールドになっています。
コンストラクタはインスタンスメソッドの一種であり、インスタンスメソッドの中から同じクラスのクラスフィールドにアクセス可能なので、インクリメントしています。
そしてインクリメントした総生産数の値を、そのインスタンスのロボットIDに代入しているのが今回のポイントです。
フィールドはstaticの有り無しに関係なく、初期値が代入されます。
数値系なら0、boolean型ならfalse、参照型ならnullが初期値です。
ローカル変数には初期値がない点も覚えておいてください。
参考図書
LINE公式アカウント
仕事が辛くてたまらない人生が、仕事が楽しくてたまらない人生に変わります。
【登録いただいた人全員に、無料キャリア相談プレゼント中!】