💡

Java Sliver 勉強⑤ カプセル化の適用

2025/03/12に公開

【出題項目の例】

  • Javaの基本データ型と文字列の操作
  • 演算子と制御構造
  • 配列の操作
  • クラスの宣言とインスタンスの使用
  • メソッドの作成と使用
  • カプセル化の適用
  • 継承による実装の再利用
  • インタフェースによる抽象化
  • 例外処理
  • モジュール・システム

カプセル化の適用

  • アクセス修飾子の使用
  • クラスに対するカプセル化の適用

アクセス修飾子の使用

Java のアクセス修飾子(Access Modifier:액세스 한정자)は、クラス・フィールド・メソッドのアクセス範囲を制限するためのキーワード
適切に使うことでデータの隠蔽(カプセル化)や安全なコード設計が可能になる。


アクセス修飾子の種類と適用範囲

修飾子 クラス内 同じパッケージ内 サブクラス(継承) 他のパッケージ
public
protected ❌(継承すればOK)
(なし)
private

アクセス修飾子の具体的な使い方

1. クラスに適用

  • public → どこからでもアクセス可能
  • (なし) → 同じパッケージ内でのみアクセス可能
// どこからでもアクセス可能
public class PublicClass {
    // クラス定義
}

// 同じパッケージ内でのみアクセス可能
class DefaultClass {
    // クラス定義
}

2. フィールド・メソッドに適用

  • private(カプセル化に重要!)
    → クラス内からのみアクセス可能
  • protected
    → 同じパッケージ + 継承関係のクラスからアクセス可能
  • public
    → どこからでもアクセス可能
public class Hero {
    private String name;  // 外部から直接アクセス不可(カプセル化)
    protected int hp;     // サブクラスからアクセス可能
    public int attackPower; // どこからでもアクセス可能

    // コンストラクタ
    public Hero(String name, int hp) {
        this.name = name;
        this.hp = hp;
    }

    // `private` フィールドのため `getter` / `setter` を用意
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    // `public` メソッド
    public void attack() {
        System.out.println(name + "の攻撃!");
    }
}

3. 継承関係での protected の使い方

  • protected を使うと、サブクラスから直接アクセスできる!
  • private だとサブクラスからは直接アクセス不可!
public class Hero {
    protected int hp = 100;  // 継承したクラスからアクセス可

    public void attack() {
        System.out.println("攻撃した!");
    }
}

public class SuperHero extends Hero {
    public void boost() {
        this.hp += 50;  // `protected` のためアクセス可
        System.out.println("HPが回復した!現在のHP:" + this.hp);
    }
}

4. privategetter / setter で制御

  • private だと直接アクセス不可!
  • getter / setter を使って安全に値を取得・変更する!
public class Hero {
    private int hp;  // 直接アクセス不可(カプセル化)

    public Hero(int hp) {
        this.hp = hp;
    }

    // `getter` で値を取得
    public int getHp() {
        return hp;
    }

    // `setter` で値を変更(0未満の値は設定不可)
    public void setHp(int hp) {
        if (hp < 0) {
            this.hp = 0;
        } else {
            this.hp = hp;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Hero hero = new Hero(100);
        
        System.out.println("初期HP: " + hero.getHp());
        hero.setHp(-50);  // 0 に補正される
        System.out.println("変更後のHP: " + hero.getHp());

        hero.setHp(80);
        System.out.println("変更後のHP: " + hero.getHp());
    }
}

ポイント

チェック項目 説明
private の特徴 カプセル化のために使用!外部から直接アクセス不可!
protected の特徴 サブクラスからアクセス可能!ただし他のパッケージでは NG!
public の特徴 どこからでもアクセス可能!
クラスにはどの修飾子を使う? 基本 public、ただしパッケージ内限定なら省略
フィールドには? 基本 private(カプセル化)→ getter / setter を使用
メソッドには? 基本 public で外部から呼び出せるようにする!

クラスに対するカプセル化の適用

  1. フィールドを private にする
    • 外部から直接アクセスできないようにする。
  2. getter / setter メソッドを定義する
    • データを取得 (getter)、変更 (setter) するメソッドを作ることで、必要な範囲でのみデータを操作できる。
  3. データの不正な変更を防ぐ
    • setter で制約を加え、無効な値がセットされないようにする。
  4. カプセル化によるメリット
    • データの保護: 外部からの不正な変更を防ぐ。
    • 保守性の向上: 内部の実装を変更しても外部への影響を最小限にできる。
    • コードの可読性向上: 明確なインターフェースを提供できる。

ポイント

  1. フィールドを private にする理由は?
    外部から直接アクセスを防ぎ、不正な変更を防ぐため。

  2. カプセル化のメリットは?

    • データの保護(無効な値を防ぐ)
    • 保守性の向上(内部の実装変更が容易)
    • 可読性向上(データの管理が明確になる)
  3. getter / setter を使用する理由は?
    getter でデータを提供し、setter でデータ変更時の制約を加えられるため。


Discussion