【2025年版】カプセル化とアクセス修飾子完全ガイド – 初心者でもわかるオブジェクト指向の基本
カプセル化とは?初心者向け解説
カプセル化(Encapsulation)は、オブジェクト指向プログラミングの三大要素の一つで、データ(フィールド)とそれを操作するメソッドを一つのクラスにまとめ、外部からの直接アクセスを制限する仕組みです。
カプセル化のメリット
- データの保護:不正な値の設定を防止
- 保守性の向上:内部実装の変更が外部に影響しない
- 再利用性の向上:安全で使いやすいクラス設計
- バグの軽減:制御されたアクセスによりエラーを防止
アクセス修飾子の種類と使い分け
Java のアクセス修飾子一覧
| 修飾子 | 同一クラス | 同一パッケージ | サブクラス | 外部パッケージ |
|---|---|---|---|---|
| public | ○ | ○ | ○ | ○ |
| protected | ○ | ○ | ○ | × |
| default | ○ | ○ | × | × |
| private | ○ | × | × | × |
1. private(最も制限的)
用途:クラス内部のデータやヘルパーメソッド
public class BankAccount {
private double balance; // 外部から直接アクセス不可
private boolean isValidAmount(double amount) {
return amount > 0;
}
}
2. public(最も開放的)
用途:外部に公開するメソッドやクラス
public class Calculator {
public double add(double a, double b) {
return a + b; // どこからでも呼び出し可能
}
}
3. protected(継承関係で使用)
用途:サブクラスに継承させたいメンバー
public class Animal {
protected String name; // サブクラスからアクセス可能
protected void sleep() {
System.out.println(name + "が眠っています");
}
}
4. default(パッケージプライベート)
用途:同一パッケージ内でのみ共有したいメンバー
class PackageHelper {
String getMessage() { // 同一パッケージ内からのみアクセス可能
return "パッケージ内メッセージ";
}
}
カプセル化の実践例
悪い例:カプセル化されていないクラス
public class BadStudent {
public String name;
public int age;
public double score; // 直接アクセス可能 = 危険
}
// 使用例:問題のあるコード
BadStudent student = new BadStudent();
student.score = -50; // 不正な値が設定可能
良い例:適切にカプセル化されたクラス
public class Student {
private String name;
private int age;
private double score;
public void setScore(double score) {
if (score >= 0 && score <= 100) {
this.score = score;
}
}
public double getScore() {
return score;
}
}
// 使用例:安全なコード
Student student = new Student();
student.setScore(-50); // 無効な値は設定されない
Getter/Setter パターンの実装
基本的な Getter/Setter
public class Person {
private String name;
private int age;
// Getter
public String getName() { return name; }
public int getAge() { return age; }
// Setter(バリデーション付き)
public void setName(String name) {
if (name != null && !name.trim().isEmpty()) {
this.name = name;
}
}
public void setAge(int age) {
if (age >= 0 && age <= 150) {
this.age = age;
}
}
}
読み取り専用プロパティ
public class ImmutableProduct {
private final String id;
private final String name;
public ImmutableProduct(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() { return id; } // Getter のみ
public String getName() { return name; } // 変更不可
}
言語別アクセス修飾子の違い
C# のアクセス修飾子
public class CSharpExample {
private int privateField;
protected int protectedField;
internal int internalField; // アセンブリ内でアクセス可能
public int publicField;
private protected int restrictedField; // C# 7.2 以降
}
Python のカプセル化
class PythonExample:
def __init__(self):
self.public = "誰でもアクセス可能"
self._protected = "慣例的にprotected"
self.__private = "プライベート(名前修飾される)"
def get_private(self):
return self.__private
JavaScript のプライベートフィールド
class JSExample {
#privateField; // ES2022 プライベートフィールド
constructor() {
this.#privateField = "プライベート";
}
getPrivate() {
return this.#privateField;
}
}
カプセル化設計のベストプラクティス
1. デフォルトは private
public class BestPractice {
private String data; // まずprivateで宣言
public String getData() { // 必要に応じてアクセサを提供
return data;
}
}
2. 不変オブジェクトの活用
public final class ImmutablePoint {
private final int x, y;
public ImmutablePoint(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() { return x; }
public int getY() { return y; }
}
3. ビルダーパターンとの組み合わせ
public class User {
private final String name;
private final String email;
private User(Builder builder) {
this.name = builder.name;
this.email = builder.email;
}
public static class Builder {
private String name, email;
public Builder setName(String name) { this.name = name; return this; }
public User build() { return new User(this); }
}
}
よくある間違いと対策
間違い1:すべてを public にする
// 悪い例
public class BadDesign {
public String name; // 直接アクセス可能
public List<String> items; // リストの中身を変更可能
}
// 良い例
public class GoodDesign {
private String name;
private List<String> items = new ArrayList<>();
public List<String> getItems() {
return new ArrayList<>(items); // 防御的コピー
}
}
間違い2:Getter/Setter の濫用
// 単純すぎる例
public class OverUsed {
private int value;
public int getValue() { return value; }
public void setValue(int value) { this.value = value; }
}
// より良い設計
public class BetterDesign {
private int balance;
public void deposit(int amount) { // 意味のあるメソッド名
if (amount > 0) balance += amount;
}
public boolean withdraw(int amount) {
if (amount > 0 && balance >= amount) {
balance -= amount;
return true;
}
return false;
}
}
実践的な学習ステップ
初級レベル
- private/public の使い分けを理解
- 基本的な Getter/Setter の実装
- フィールドの直接アクセスを避ける習慣
中級レベル
- protected の適切な使用場面を理解
- 不変オブジェクトの設計
- 防御的プログラミングの実践
上級レベル
- アクセス制御とセキュリティの関係
- API 設計におけるカプセル化
- フレームワーク設計での応用
まとめ
カプセル化とアクセス修飾子は、オブジェクト指向プログラミングの基礎であり、保守性の高いコードを書くために欠かせない概念です。適切なアクセス制御により、データの整合性を保ち、クラスの責任を明確にできます。
実際のプロジェクトでは、まずデフォルトで private を使用し、必要に応じて段階的にアクセス範囲を広げる設計アプローチを推奨します。カプセル化をマスターすることで、より安全で再利用可能なコードが書けるようになります。
■プロンプトだけでオリジナルアプリを開発・公開してみた!!
■AI時代の第一歩!「AI駆動開発コース」はじめました!
テックジム東京本校で先行開始。
■テックジム東京本校
「武田塾」のプログラミング版といえば「テックジム」。
講義動画なし、教科書なし。「進捗管理とコーチング」で効率学習。
より早く、より安く、しかも対面型のプログラミングスクールです。
<短期講習>5日で5万円の「Pythonミニキャンプ」開催中。
<月1開催>放送作家による映像ディレクター養成講座
<オンライン無料>ゼロから始めるPython爆速講座




