インスタンス変数 vs 静的変数
CoddyのJavaジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 15/87。
これまで作成したすべてのフィールドは、特定のオブジェクトに属しています。各BankAccountには独自のbalanceがあり、各Productには独自のnameがあります。これらはインスタンス変数です。クラスの各インスタンスごとに個別に存在します。
しかし、すべてのオブジェクトで共有されるデータが必要な場合はどうでしょうか?そこで登場するのが静的変数(クラス変数とも呼ばれます)です。静的変数は特定のオブジェクトではなく、クラス自体に属します。
public class Student {
private String name; // インスタンス変数 - 学生ごとに固有
private static int totalCount; // 静的変数 - すべての学生で共有
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 オブジェクトで共有され、作成された本の数を追跡 - title と price を受け取り、本の総数を増加させるコンストラクター
- title 用のゲッター
getTitle() - price 用のゲッター
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: 静的メソッドを使って本の総数を出力する
// Format: Total books: [count]
// 静的メソッドにはクラス名を通じてアクセスすることを忘れないでください: Book.getTotalBooks()
}
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
4継承
継承の基本 (extends)super キーワードメソッドのオーバーライド (@Override)コンストラクタチェーンObject クラス単一継承と多段階継承なぜ多重継承ができないのかまとめ:従業員の階層構造自分で練習してみよう: Javaオンラインコンパイラ