【JAVA】レッスン5-04:クラスメンバとインスタンスメンバを理解しよう

記事内に商品プロモーションを含む場合があります

この記事で学べる知識:クラスメンバ、インスタンスメンバ

この記事の練習問題で使用する知識:
基礎構文、制御構造、メソッド、コレクション(レッスン1~4)クラスの定義と使用コンストラクタカプセル化クラスメンバとインスタンスメンバメソッドのオーバーライドクラスの継承抽象クラスインターフェース

<<前のページ JAVA Topへ 次のページ>>

JAVAの文法「クラスメンバとインスタンスメンバ」とは

ここではクラスメンバとインスタンスメンバの意味や使い方を学習します。必要ない方はここをクリックして練習問題へ飛びましょう。

Javaのクラスでは「クラスメンバ」と「インスタンスメンバ」が重要な役割を果たします。

これらはプログラム内でデータを管理し、操作するための基盤です。

クラスメンバとインスタンスメンバの違いや役割を理解することで、より効率的で管理しやすいコードを書くことができるようになります。

クラスメンバとインスタンスメンバとは?

クラスメンバとインスタンスメンバは、どちらもクラスに含まれる要素のことです。

クラスメンバは「クラス全体で共有される」ものであり、インスタンスメンバは「各インスタンス(オブジェクト)ごとに持つ」ものを指します。

・クラスメンバ:クラス全体で使用される変数やメソッド
・インスタンスメンバ:インスタンスごとに異なるデータを保持する変数やメソッド

クラスメンバの定義と使用例

クラスメンバはクラス全体で使用される変数やメソッドをいい、それぞれクラス変数クラスメソッドと呼びます。

クラスメンバはstaticキーワードを用いて定義されます。

これによりすべてのインスタンスで共通の値を保持し、クラスから直接アクセスすることができます。

以下にクラスメンバの使用例を示します。

public class Counter {
    // クラス変数
    static int count = 0;

    // クラスメソッド
    public static void increment() {
        count++;
    }
}

この例ではcountはクラス変数として定義され、すべてのインスタンスで共有されるため、どのインスタンスからでもcountにアクセスしてその値を確認できます。

またincrementメソッドもクラスメソッドとして定義されており、クラス名を使って直接呼び出すことが可能です(Counter.increment())。

インスタンスメンバの定義と使用例

インスタンスメンバはインスタンスごとに異なるデータを保持する変数やメソッドをいい、それぞれインスタンス変数インスタンスメソッドと呼びます。

インスタンスメンバは各インスタンスごとに独立した値を持つため、staticキーワードを使用せずに定義されます。

以下にインスタンスメンバの使用例を示します。

public class Person {
    // インスタンス変数
    String name;

    // インスタンスメソッド
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return this.name;
    }
}

この例では、nameはインスタンス変数として定義され、各インスタンスごとに異なる値を持ちます。

setNameおよびgetNameはインスタンスメソッドであり、インスタンスごとにnameの値を設定および取得するために使用します。

thisキーワードはそのインスタンス自身を指すために用いられます。

クラスメンバとインスタンスメンバの違いと比較

クラスメンバとインスタンスメンバには、以下のような違いがあります。

特徴 クラスメンバ インスタンスメンバ
キーワード static なし
メモリの共有 すべてのインスタンスで共有 各インスタンスごとに独立
アクセス方法 クラス名で直接アクセス インスタンスを通してアクセス
使用する場面 共通データやユーティリティメソッド 個別のデータやオブジェクト固有の動作

クラスメンバはstaticキーワードを使って宣言され、すべてのインスタンスで同じデータを共有するため、メモリの節約や共通機能の提供に適しています。

一方でインスタンスメンバはインスタンスごとに独立してデータを保持できるため、個別のデータや振る舞いが必要な場合に使用されます。

これらを使い分けることで、より効率的で可読性の高いコードが実現できます。

まとめ

Javaのクラスメンバとインスタンスメンバは、コードの管理や処理を効率化するために重要な役割を果たします。

クラス全体で共通の値やメソッドが必要な場合はクラスメンバを、各インスタンスごとに異なるデータや処理が必要な場合はインスタンスメンバを選択するようにしましょう。

JAVA練習問題5-4:クラスメンバとインスタンスメンバ使い分けよう

図書館の蔵書を管理するためのプログラムを作成しましょう。

このプログラムでは全体の蔵書数をクラスメンバ(クラス変数)で管理し、各図書の名前をインスタンスメンバ(インスタンス変数)で保持します。

本を追加するたびに総蔵書数が増加するようにし、それぞれの本の名前と総蔵書数を表示するメソッドを作成してください。

この問題の要件

以下の要件に従いプログラムを作成して下さい。

  1. Libraryというクラスを作成し、以下のように定義すること。
    • クラス変数totalBooksを定義し、初期値は0とすること。この変数は全体の蔵書数を保持する。
    • インスタンス変数bookNameを定義し、本の名前を保持する。
  2. コンストラクタを定義し、引数として本の名前を受け取り、インスタンス変数bookNameにその名前を設定すること。
    • また、クラス変数totalBooksを1増加させること。
  3. クラスメソッドdisplayTotalBooksを定義し、現在の蔵書数(totalBooksの値)を出力すること。
  4. インスタンスメソッドdisplayBookNameを定義し、その本の名前(bookNameの値)を出力すること。
  5. mainメソッドで以下を実行すること:
    • 図書館に本を2冊追加し、それぞれの本の名前を表示すること。
    • 総蔵書数を表示すること

ただし、以下のような実行結果となること。

----- ↓出力される結果の例↓ -----

本の名前: Java入門
本の名前: プログラミング基礎
総本数: 2

この問題を解くヒント

1からコードを組み立てることが難しい場合は、以下のヒントを開いて参考にしましょう。

ヒント1【コードの構成を見る】

正解のコードは上から順に以下のような構成となっています。

1:Libraryクラスの定義
  □ クラス変数totalBooksの定義と初期化
  □ インスタンス変数bookNameの宣言
  □ コンストラクタの定義
  □ □ 引数namebookNameに設定
  □ □ クラス変数totalBooksを1増加
  □ クラスメソッドdisplayTotalBooksの定義
  □ □ 総本数を表示
  □ インスタンスメソッドdisplayBookNameの定義
  □ □ bookNameを表示
  □ mainメソッドの定義
  □ □ Libraryクラスのインスタンスbook1を生成し、”Java入門”を設定
  □ □ Libraryクラスのインスタンスbook2を生成し、”プログラミング基礎”を設定
  □ □ book1displayBookNameメソッドを呼び出し、名前を表示
  □ □ book2displayBookNameメソッドを呼び出し、名前を表示
  □ □ displayTotalBooksメソッドを呼び出し、総本数を表示

ヒント2【穴埋め問題にする】

以下のコードをコピーし、コメントに従ってコードを完成させて下さい。

public class Library {
    // クラスメンバ(クラス変数):すべてのインスタンスで共有されるカウンタ
    /* 【穴埋め問題1】
    ここにクラス変数を定義し、初期値を0に設定するコードを書いてください。
    */

    // インスタンスメンバ(インスタンス変数):各インスタンスごとに異なる本の名前
    /* 【穴埋め問題2】
    ここにインスタンス変数を定義し、本の名前を格納できるようにするコードを書いてください。
    */

    // コンストラクタ:新しい本を追加するときに本の名前を設定し、クラスメンバのカウンタを増加させる
    public Library(String name) {
        /* 【穴埋め問題3】
        ここでインスタンス変数に引数nameを代入するコードを書いてください。
        */
        
        /* 【穴埋め問題4】
        ここでクラス変数を1増加させるコードを書いてください。
        */
    }

    // クラスメソッド:総本数を出力する(クラスメンバの値を表示)
    public static void displayTotalBooks() {
        /* 【穴埋め問題5】
        ここでクラス変数totalBooksの値を出力するコードを書いてください。
        */
    }

    // インスタンスメソッド:本の名前を出力する(インスタンスメンバの値を表示)
    public void displayBookName() {
        /* 【穴埋め問題6】
        ここでインスタンス変数bookNameの値を出力するコードを書いてください。
        */
    }

    public static void main(String[] args) {
        // 2つの本のインスタンスを作成
        Library book1 = new Library("Java入門");
        Library book2 = new Library("プログラミング基礎");

        // 各インスタンスの本の名前を表示
        book1.displayBookName();
        book2.displayBookName();

        // 総本数を表示(クラスメンバの使用)
        Library.displayTotalBooks();
    }
}

この問題の穴埋めコードは以上です。

このヒントを見てもまだ回答を導き出すのが難しいと感じる場合は、先に正解のコードと解説を見て内容を理解するようにしましょう。

解答例と解説

この問題の一つの正解例とそのコードの解説を以下に示します。

正解コードの例

例えば以下のようなプログラムが考えられます。

public class Library {
    // クラスメンバ(クラス変数):すべてのインスタンスで共有されるカウンタ
    static int totalBooks = 0;

    // インスタンスメンバ(インスタンス変数):各インスタンスごとに異なる本の名前
    private String bookName;

    // コンストラクタ:新しい本を追加するときに本の名前を設定し、クラスメンバのカウンタを増加させる
    public Library(String name) {
        this.bookName = name;  // インスタンス変数に値を設定
        totalBooks++;          // クラス変数を増加
    }

    // クラスメソッド:総本数を出力する(クラスメンバの値を表示)
    public static void displayTotalBooks() {
        System.out.println("総本数: " + totalBooks);
    }

    // インスタンスメソッド:本の名前を出力する(インスタンスメンバの値を表示)
    public void displayBookName() {
        System.out.println("本の名前: " + this.bookName);
    }

    public static void main(String[] args) {
        // 2つの本のインスタンスを作成
        Library book1 = new Library("Java入門");
        Library book2 = new Library("プログラミング基礎");

        // 各インスタンスの本の名前を表示
        book1.displayBookName();
        book2.displayBookName();

        // 総本数を表示(クラスメンバの使用)
        Library.displayTotalBooks();
    }
}

正解コードの解説

このコードは図書館の蔵書数を管理するシンプルなプログラムで、クラスメンバとインスタンスメンバがどのように役立つかを理解するのに適しています。

以下にブロックごとに解説します。

クラスの定義とクラス変数(クラスメンバ)

public class Library {
    static int totalBooks = 0;

ここではLibraryというクラスを定義し、その中にtotalBooksというクラス変数(クラスメンバ)を設定しています。

このtotalBooksstaticキーワードを使って宣言されています。クラスメンバはクラス全体で共有され、すべてのインスタンスで共通の値を保持します

つまりLibraryクラスのインスタンスが複数作られても、totalBooksの値はすべてのインスタンスで共通になります。

インスタンス変数(インスタンスメンバ)の定義

    private String bookName;

bookNameはインスタンス変数(インスタンスメンバ)です。

privateキーワードを使ってカプセル化されているため、クラス外から直接アクセスすることはできません。

インスタンスメンバは各インスタンスごとに独立した値を保持するため、複数のインスタンスが異なる本の名前を保持することができます

コンストラクタの定義

    public Library(String name) {
        this.bookName = name;
        totalBooks++;
    }

コンストラクタは新しいインスタンスが作成された際に実行される特別なメソッドです。

ここではbookNameに本の名前を設定し、クラス変数totalBooksの値を1増加させています。

これにより新しい本が追加されるたびに、図書館の総蔵書数が自動的に更新されます

クラスメソッドとインスタンスメソッド

    public static void displayTotalBooks() {
        System.out.println("総本数: " + totalBooks);
    }
    
    public void displayBookName() {
        System.out.println("本の名前: " + this.bookName);
    }

displayTotalBooksはクラスメソッドであり、staticキーワードが付いています。

クラスメソッドはクラス名を使って直接呼び出すことができ、インスタンスを通さなくても利用可能です。

一方displayBookNameはインスタンスメソッドであり、インスタンスごとに異なる本の名前を表示します。

このようにクラスメソッドはクラス全体で共有されるデータを扱い、インスタンスメソッドは各インスタンス固有のデータを操作することが一般的です

メインメソッド:プログラムの実行

    public static void main(String[] args) {
        Library book1 = new Library("Java入門");
        Library book2 = new Library("プログラミング基礎");

        book1.displayBookName();
        book2.displayBookName();

        Library.displayTotalBooks();
    }
}

mainメソッドではLibraryクラスのインスタンスを2つ作成し、それぞれ異なる本の名前を設定しています。

その後、各インスタンスの名前を表示し、最終的に図書館の総蔵書数をクラスメソッドで表示します。

この部分は、クラスメンバとインスタンスメンバの使い分けを実際のコードで確認する良い例です

まとめ

今回のコードを通じてクラスメンバとインスタンスメンバの違いや役割を学びました

クラスメンバは全体で共有され、インスタンスメンバはオブジェクトごとに異なるデータを保持するため、使い分けが重要です。

クラスとオブジェクトの違いを意識しながら、実際のプログラムに活用してみましょう。

<<前のページ JAVA Topへ 次のページ>>

この問題への質問・コメント

この問題を作成するにあたりAIを活用しています。

問題ないことは確認していますが、もし間違いや表現の違和感などありましたら、ご指摘頂けると大変助かります。






    JAVAテキスト&問題集へ戻る
    トップページへ戻る