今回やること
クラスは、関連するデータと処理をまとめた新しい型です。本を表すBookクラスを一段ずつ作り、2冊の本を別々のオブジェクトとして扱います。
前提: Java入門 #11 - メソッドの定義と呼び出しを終え、引数と戻り値の基本を理解していること。
| 言葉 | この例での意味 |
|---|---|
| クラス | 本の共通構造を定義するBook |
| フィールド | 各本が持つtitleとprice |
| メソッド | 本の情報を表示するshowInfo() |
| オブジェクト | new Book(...)で作った1冊分の実体 |
クラスを使わず、title1、price1、title2、price2のように変数を増やすと、どのタイトルと価格が同じ本なのか分かりにくくなります。Bookにまとめると、1冊分のデータと処理を一つの単位として受け渡せます。
Bookクラス
├── first → title="Java入門", price=1800
└── second → title="Webのしくみ", price=2200
1. フィールドを決める
最初に、本が持つデータをクラスへ書きます。
class Book {
String title;
int price;
}
この段階では「本にはタイトルと価格がある」と定義しただけです。Book型の実体はまだありません。
フィールドはクラスの波括弧の中、メソッドの外へ書きます。mainの中で宣言するローカル変数とは違い、オブジェクトが存在する間、そのオブジェクトの状態として保持されます。
2. 作成時に値を受け取る
クラス名と同じ名前のコンストラクタを追加します。newした時に受け取った値を、オブジェクト自身のフィールドへ入れます。
Book(String title, int price) {
this.title = title;
this.price = price;
}
this.titleはフィールド、右側のtitleは引数です。名前が同じ時にthisで区別します。コンストラクタの詳しい使い分けは次の記事で扱います。
3. メソッドを追加する
本が持つデータを使う処理を、同じクラスへまとめます。
void showInfo() {
System.out.println(title + ":" + price + "円");
}
showInfo()は呼び出されたオブジェクトのtitleとpriceを使います。
引数を渡していないのに本ごとに違う表示になるのは、first.showInfo()ならfirstのフィールド、second.showInfo()ならsecondのフィールドを読むからです。メソッドの前にある変数が「どのオブジェクトへ処理を頼むか」を表します。
完成コードを動かす
BookDemo.javaとして保存します。
class Book {
String title;
int price;
Book(String title, int price) {
this.title = title;
this.price = price;
}
void showInfo() {
System.out.println(title + ":" + price + "円");
}
}
public class BookDemo {
public static void main(String[] args) {
Book first = new Book("Java入門", 1800);
Book second = new Book("Webのしくみ", 2200);
first.showInfo();
second.showInfo();
}
}
javac BookDemo.java
java BookDemo
firstとsecondは同じBook型ですが、別のフィールド値を持つ別オブジェクトです。一方の価格を変えても、もう一方は変わりません。
実行の流れは次のとおりです。
| 行 | 起きること |
|---|---|
new Book("Java入門", 1800) | 1冊目を作り、コンストラクタで値を入れる |
new Book("Webのしくみ", 2200) | 2冊目を別に作る |
first.showInfo() | 1冊目のフィールドを表示する |
second.showInfo() | 2冊目のフィールドを表示する |
変数firstとsecondには、オブジェクトそのものをコピーした値ではなく、作ったオブジェクトを参照するための情報が入ります。今は「変数を通して対象のオブジェクトを操作する」と理解できれば十分です。
成功確認
次の2行が表示されれば成功です。
Java入門:1800円
Webのしくみ:2200円
クラスを一度定義し、newを2回使って異なる本を作れたことを確認してください。
よくあるつまずき
ファイル名とpublic class名が違う
public class BookDemoを含むため、ファイル名はBookDemo.javaです。Book.javaではありません。
newを書かずに使う
クラス定義だけではオブジェクトは作られません。Book first = new Book(...)のように、newで実体を作ります。
thisを外して値が入らない
引数とフィールドが同名なら、this.title = titleと書きます。title = titleでは引数へ同じ値を代入するだけです。
すべてを一つのクラスへ入れる
クラスは、関係するデータと処理をまとめる単位です。本と利用者のように役割が違うものまで同じクラスへ押し込まず、まず「何を1個として扱いたいか」を一文で決めます。
練習
映画を表すMovieクラスを作ってください。titleとminutesを持たせ、showInfo()で「映画名:120分」のように表示します。2本の映画をnewで作れれば完了です。
次のステップ
Java入門 #13 - コンストラクタで、初期値の設定とコンストラクタのオーバーロードを学びます。