【Javaで実装】オブジェクト指向のカプセル化 (setter/getter)— 初心者向け

IT

この記事を読んで分かること

・カプセル化とは

・Javaでカプセル化の実装方法

オブジェクト指向のカプセル化は、コードの安全性・保守性を高めるための概念・考え方です。

カプセル化について、図解でイメージしたい方はこちらの記事を参考してみてください。

Javaではカプセル化を文法(privateやgetter/setter)で簡単に実装できます。本記事では「なぜカプセル化が必要なのか」実践的なサンプルを用いて解説します。最終的には、ただ動くコードではなく「設計の意図を持ったコード作り」ができるように理解を深めていきましょう。

【復習】カプセル化とは

カプセル化とは、「データ(中身)」を外部の操作から守る仕組みのことです。

「データ(中身)とそれを操作するメソッドを一つのオブジェクトにまとめ、外部から直接操作させない」設計です。外部は公開されたインターフェース(メソッド)を通してしか内部状態に触れられないため、クラス内部の実装を変更しても外部に影響を与えにくくなります。これにより、不正な状態遷移の防止、バグの局所化など保守性を高めます。

目的・意図

主な目的は「安全性」と「可読性/保守性」の両立です。安全性では不正な値設定を防ぎ、一貫性のある状態を保証します(例:口座残高がマイナスにならない)。可読性では、APIだけを見ればそのクラスの使い方が分かり、内部実装は隠れているためリファクタリングしやすくなります。また設計意図をソースコードで示すことで、チーム開発時に誤用を避けられます。

Javaでの基本実装

Javaではフィールドをprivateにして外部から直接触れられないようにし、必要な操作だけpublicメソッドで提供します。基本パターンは

①フィールドをprivateにする

②値取得用のgetter()

③値設定用のsetter()です。

最近は「不変オブジェクト(setterを持たない)」やLombok等の補助ツールもありますが、getter/setterをつけることでより汎用性の高いコーディングを目指していきましょう。

実装例

今回は学生のテスト点数を安全に管理するクラスをサンプルとして扱います。
外部からの直接アクセスを防ぎ、メソッドを通してのみ点数を変更できるようにしています。
メソッド名・コメント・例外を使って、「何を許可し、何を禁止するか」が明確に読み取れる構成にしています。

★StudentScore.java

public class StudentScore {
    
    // フィールドは外部から直接操作できないように private にする
    private String studentName;
    private int score;

    // コンストラクタ
    public StudentScore(String studentName, int score) {
        this.studentName = studentName;
        setScore(score); //setterで点数を設定
    }

    // getter 名前
    public String getStudentName() {
        return studentName;
    }

    // getter 点数
    public int getScore() {
        return score;
    }

    // setter 点数
    public void setScore(int score) {

        // 0 ~ 100の点数の処理理
        if (score < 0 || score > 100) {
            throw new IllegalArgumentException("点数は0〜100の範囲で指定してください。");
        }
        this.score = score;
    }

    // getter 成績(内部ロジック)
    public String getGrade() {
        if (score >= 90) return "A";
        else if (score >= 75) return "B";
        else if (score >= 60) return "C";
        else return "D";
    }

    // 点数を上げるメソッド。
    public void addBonus(int bonus) {
        if (bonus < 0) throw new IllegalArgumentException("ボーナス点は正の値で指定してください。");
        // setterで点数を設定
        setScore(this.score + bonus); 
    }
}

★Main.java

public class Main {
    public static void main(String[] args) {

        // 学生オブジェクトを生成(インスタンス化)
        StudentScore student = new StudentScore("佐藤", 85);


        System.out.println("学生名: " + student.getStudentName());
        System.out.println("初期点数: " + student.getScore());
        System.out.println("成績: " + student.getGrade());
        System.out.println("-----------------------------");


        // ボーナス点を加算
        student.addBonus(10);
        System.out.println("ボーナス加算後の点数: " + student.getScore());
        System.out.println("成績: " + student.getGrade());
        System.out.println("-----------------------------");


        // 例外:範囲外の値(120点)
        try {
            student.setScore(120);
        } catch (IllegalArgumentException e) {
            System.out.println("不正な点数を設定 :" + e.getMessage());
        }

        // 不正な操作例2:privateフィールドに直接アクセスしようとする(※コンパイルエラーになります)
        // student.score = 50; // ← この行を有効にするとコンパイルエラー

        System.out.println("-----------------------------");
        System.out.println("最終的な点数: " + student.getScore());
        System.out.println("最終的な成績: " + student.getGrade());
    }
}

実行結果

上記のソースコードを実行します。

実行方法

①javac *.java

②java Main

※VScodeのターミナルで実行しています。

この実行結果から、以下のことが確認できます:

  1. 外部からの直接アクセスは禁止(private
     → student.score = 50; はコンパイルエラーになる。
     (外部クラスからscoreを操作できない)
  2. setScore()を通じてのみ状態を変更可能
     → scoreの値は常に0〜100の範囲に制限される。
  3. 例外で不正操作を防止
     → 範囲外の値(120点など)はIllegalArgumentExceptionで拒否。
  4. addBonus()で点数を変更可能
     → 内部的にsetScore()を呼び出すことで常にバリデーションを維持。

これにより、内部データが守られ、意図しない改ざんが不可能な状態が確認できます。
カプセル化の目的である「安全性・保守性を担保する」ことが達成できます。

まとめ

ここまで、カプセル化とは何か、Javaでの実装方法を紹介しました。カプセル化はデータ(中身)を外部から操作・改ざんされない仕組みであり、Javaではprivateフィールド+publicメソッド(getter/setter)で実装してみました。

最後までご覧いただきありがとうございました。何か分からないことなどありましたら、コメントもしくは、Xにてご連絡ください。

タイトルとURLをコピーしました