09_クラスとインスタンス

対象:C言語経験者 / C言語の構造体との比較でクラスを理解します


■ 1. クラスとは何か

C言語の構造体(struct)を思い出してください。構造体は「関連するデータをまとめる箱」でした。Javaのクラスはそれをさらに強化したものです。

C言語の構造体
struct Person {
    char name[50];
    int age;
};
// データだけ。処理は別の関数に書く
Javaのクラス
class Person {
    String name;  // フィールド(データ)
    int age;

    void greet() {  // メソッド(処理)
        System.out.println("私は" + name);
    }
}
クラスは「データ(フィールド)」と「処理(メソッド)」をひとつにまとめたものです。
C言語の構造体と関数を一体化したイメージです。
クラス(Person) フィールド(データ) String name int age C言語の構造体メンバに相当 メソッド(処理) void greet() int getAge() C言語の関数に相当
クラスはデータと処理をひとつにまとめた「設計図」です

■ 2. インスタンスとは何か

クラスは「設計図」です。設計図だけではプログラムは動きません。設計図をもとに実体を作ったものが インスタンス です。

C言語(構造体変数)
struct Person p1;
strcpy(p1.name, "Taro");
p1.age = 20;
Java(インスタンス生成)
Person p1 = new Person();
p1.name = "Taro";
p1.age = 20;
Person クラス (設計図) name, age greet() new p1(インスタンス) name="Taro", age=20 p2(インスタンス) name="Hana", age=22 同じ設計図から 複数のインスタンスを 作れます
クラス(設計図)から new でインスタンス(実体)を作ります

■ 3. コンストラクタ

インスタンス生成時に自動で呼ばれる特別なメソッドです。フィールドの初期値を設定するために使います。

C言語には対応する機能がありません(初期化は自分でやっていました)。

class Person {
    String name;
    int    age;

    // コンストラクタ:クラス名と同じ名前、戻り値なし
    Person(String n, int a) {
        name = n;
        age  = a;
    }

    void greet() {
        System.out.println("私は " + name + "(" + age + "歳)です。");
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("Taro", 20);  // コンストラクタが呼ばれる
        Person p2 = new Person("Hana", 22);

        p1.greet();   // → 私は Taro(20歳)です。
        p2.greet();   // → 私は Hana(22歳)です。
    }
}
項目内容
名前クラス名と同じ
戻り値なし(void も書かない)
呼び出しタイミングnew したときに自動で呼ばれます
省略した場合引数なしのデフォルトコンストラクタが自動生成されます

■ 4. this キーワード

引数名とフィールド名が同じになるとき、this. でフィールドを明示します。

Person(String name, int age) {
    this.name = name;  // this.name = フィールド、name = 引数
    this.age  = age;
}
this は「このインスタンス自身」を指します。C言語にはない概念です。

■ 実習:Personクラスを作って動かす

実習

09_Class フォルダに PersonMain.java を1ファイルで作って実行しましょう。

// 1つのファイルに複数のクラスを書ける(public は1つだけ)
class Person {
    String name;
    int    age;

    Person(String name, int age) {
        this.name = name;
        this.age  = age;
    }

    void greet() {
        System.out.println("こんにちは、" + name + "です。" + age + "歳です。");
    }

    boolean isAdult() {
        return age >= 18;
    }
}

public class PersonMain {
    public static void main(String[] args) {
        Person p1 = new Person("Taro", 20);
        Person p2 = new Person("Hana", 15);

        p1.greet();
        p2.greet();

        System.out.println("Taro 成人?: " + p1.isAdult());
        System.out.println("Hana 成人?: " + p2.isAdult());
    }
}

実行結果:

こんにちは、Taroです。20歳です。 こんにちは、Hanaです。15歳です。 Taro 成人?: true Hana 成人?: false

● 動いたら変えてみましょう

#変えてみること確認ポイント
1Person p3 = new Person("Jun", 18); を追加して greet()isAdult() を呼ぶ同じ設計図から3つ目のインスタンスが作れることを確認しましょう
2フィールドに String job; を追加してコンストラクタと greet() も更新する設計図(クラス)を変えると全インスタンスに影響します
3p1.age = 999; とフィールドを直接変更してみる今はできてしまいます。次の単元でカプセル化(private)を学びます

試験(問2)との対応

用語意味
クラス設計図。フィールドとメソッドをまとめたもの
インスタンスクラスから new で作った実体
フィールド(メンバ変数)クラスが持つデータ
メソッドクラスが持つ処理
コンストラクタnew 時に自動で呼ばれる初期化メソッド
メッセージインスタンスに対してメソッド実行を依頼すること(p1.greet()

■ まとめ

ポイント内容
クラス設計図。フィールド(データ)とメソッド(処理)をひとつにまとめたもの
インスタンスnew で生成した実体。同じクラスから複数作れます
コンストラクタクラス名と同じ名前、戻り値なし。new 時に自動呼び出し
thisインスタンス自身を指します。引数とフィールドの名前が同じとき使います