インスタンス変数 vs 静的変数
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部 — レッスン 15/87。
これまで、作成したすべてのフィールドは特定のオブジェクトに属していました。各 BankAccount は独自の balance を持ち、各 Product は独自の name を持っています。これらは インスタンス変数 です。これらはクラスのインスタンスごとに個別に存在します。
しかし、すべてのオブジェクトで共有されるデータが必要な場合はどうすればよいでしょうか?そこで静的変数(クラス変数とも呼ばれます)の出番です。静的変数は、特定のオブジェクトではなく、クラス自体に属します。
public class Student {
private String name; // インスタンス変数 - 各学生に固有
private static int totalCount; // static変数 - すべての学生で共有
public Student(String name) {
this.name = name;
totalCount++; // 共有カウンターをインクリメント
}
public static int getTotalCount() {
return totalCount;
}
}複数の学生を作成すると、それぞれが独自の name を持ちますが、すべてが同じ totalCount を共有します:
Student s1 = new Student("Alice");
Student s2 = new Student("Bob");
System.out.println(Student.getTotalCount()); // 出力: 2オブジェクト経由ではなく、クラス名(Student.getTotalCount())を通じて静的変数にアクセスしていることに注目してください。これは、静的メンバがインスタンスではなくクラスに属していることを強調しています。
オブジェクトごとに異なるデータ(生徒の名前など)にはインスタンス変数を使用します。共有されるべきデータ(存在するオブジェクトの数をカウントするなど)には静的変数を使用します。
チャレンジ
簡単インスタンス変数と静的変数を使用して、個々の本の詳細とコレクション全体の総冊数の両方を追跡する Book 在庫システムを構築しましょう。
コードを整理するために2つのファイルを作成します:
Book.java: 個々の本の情報を追跡しながら、これまでに作成されたすべての本の数をカウントする Book クラスを作成します:- インスタンス変数
title(String) - 各本に固有 - インスタンス変数
price(double) - 各本に固有 - 静的変数
totalBooks(int) - すべての Book オブジェクトで共有され、作成された本の数を追跡します - タイトルと価格を受け取り、本の総数をインクリメントするコンストラクタ
- タイトルのためのゲッター
getTitle() - 価格のためのゲッター
getPrice() - 作成された本の総数を返す静的メソッド
getTotalBooks()
- インスタンス変数
Main.java: 複数の Book オブジェクトを作成し、静的カウンターがすべてのインスタンスをどのように追跡するかを示します。3つの本のタイトルと3つの価格を入力として受け取ります。3つの本をすべて作成した後、4行出力してください:- 各本のタイトルと価格を次の形式で出力:
[title]: $[price](価格は小数点以下2桁にフォーマット) - 静的メソッドを使用した本の総数:
Total books: [count]
- 各本のタイトルと価格を次の形式で出力:
title1, price1, title2, price2, title3, price3 の順に6つの入力を受け取ります。
静的メソッドには、オブジェクトのインスタンス経由ではなく、クラス名 (Book.getTotalBooks()) を通じてアクセスすることを忘れないでください。価格のフォーマットには、String.format("%.2f", price) を使用してください。
自分で試してみよう
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
// 3冊の本の入力を読み込む
String title1 = scanner.nextLine();
double price1 = Double.parseDouble(scanner.nextLine());
String title2 = scanner.nextLine();
double price2 = Double.parseDouble(scanner.nextLine());
String title3 = scanner.nextLine();
double price3 = Double.parseDouble(scanner.nextLine());
// TODO: 上記の入力を使用して3つの Book オブジェクトを作成する
// TODO: 各本のタイトルと価格を次の形式で出力する: [title]: $[price]
// 価格を小数点以下2桁にフォーマットするには String.format("%.2f", price) を使用する
// TODO: static メソッドを使用して本の総数を出力する
// 形式: Total books: [count]
// static メソッドにはクラス名を通じてアクセスすることを忘れないこと: Book.getTotalBooks()
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造