Javaの基礎Java

Javaの基礎:カプセル化を解説(ゲッター、セッター)

Javaカプセル化解説ページのアイキャッチ画像 Javaの基礎

この記事では、オブジェクト指向プログラミングの重要な概念であるカプセル化について理解することができます。カプセル化の基本概念を解説し、学生情報の管理と銀行口座の管理という2つの実践的なプログラム例を通じて、その適用方法を学びます。

はじめに

この記事のコードをコピペしてEclipseで出力結果を確認してみよう

カプセル化の基本

カプセル化とは、クラスの内部データ(フィールド)を外部から直接アクセスできないようにし、代わりにメソッドを通じてアクセスする仕組みです。これにより、データの整合性を保ち、クラスの実装詳細を隠蔽することができます。

カプセル化の主な特徴は以下の通りです:

  1. フィールドをprivateにする
  2. フィールドにアクセスするためのpublicなゲッター(getter)とセッター(setter)メソッドを提供する
  3. 必要に応じてゲッターやセッター内でデータの検証や加工を行う

プログラム例1: 学生情報の管理

Student.java

Java
public class Student {
    // privateフィールド
    private String name;
    private int age;

    // コンストラクタ
    public Student(String name, int age) {
        this.name = name;
        setAge(age); // セッターを使用して年齢を設定
    }

    // 名前のゲッター
    public String getName() {
        return name;
    }

    // 名前のセッター
    public void setName(String name) {
        this.name = name;
    }

    // 年齢のゲッター
    public int getAge() {
        return age;
    }

    // 年齢のセッター(値の検証あり)
    public void setAge(int age) {
        if (age >= 0 && age <= 120) {
            this.age = age;
        } else {
            System.out.println("無効な年齢です。");
        }
    }
}

Main.java

Java
public class Main {
    public static void main(String[] args) {
        // Studentオブジェクトの作成
        Student student1 = new Student("山田太郎", 20);
        Student student2 = new Student("佐藤花子", 22);

        // 学生情報の表示
        System.out.println("学生1の情報:");
        displayStudentInfo(student1);

        System.out.println("\n学生2の情報:");
        displayStudentInfo(student2);

        // 学生情報の更新
        student1.setName("山田次郎");
        student1.setAge(21);

        System.out.println("\n更新後の学生1の情報:");
        displayStudentInfo(student1);

        // 無効な年齢でのテスト
        student2.setAge(150);
    }

    // 学生情報を表示するメソッド
    private static void displayStudentInfo(Student student) {
        System.out.println("名前: " + student.getName());
        System.out.println("年齢: " + student.getAge());
    }
}

出力結果:

学生1の情報:
名前: 山田太郎
年齢: 20

学生2の情報:
名前: 佐藤花子
年齢: 22

更新後の学生1の情報:
名前: 山田次郎
年齢: 21
無効な年齢です。

Student.javaの解説

  • クラス定義
Java
public class Student {
    // ...
}

Student という名前の公開クラスを定義しています。

  • プライベートフィールド
Java
private String name;
private String age;

クラス内でprivateキーワードを使用して、nameageフィールドを定義しています。これらのフィールドは直接外部からアクセスできません。

  • コンストラクタ
Java
public Student(String name, int age) {
    this.name = name;
    setAge(age); // セッターを使用して年齢を設定
}

Studentクラスのコンストラクタを定義しています。nameは直接設定し、ageはセッターメソッドを通して設定しています。

  • 名前のゲッター
Java
public String getName() {
    return name;
}

nameフィールドの値を取得するためのゲッターメソッドです。

  • 名前のセッター
Java
public void setName(String name) {
    this.name = name;
}

nameフィールドの値を設定するためのセッターメソッドです。

  • 年齢のゲッター
Java
public int getAge() {
    return age;
}

ageフィールドの値を取得するためのゲッターメソッドです。

  • 年齢のセッター(値の検証あり)
Java
public void setAge(int age) {
    if (age >= 0 && age <= 120) {
        this.age = age;
    } else {
        System.out.println("無効な年齢です。");
    }
}

ageフィールドの値を設定するためのセッターメソッドです。このメソッドには値の検証ロジックが含まれており、年齢が0から120の範囲内にある場合のみ値を設定します。

このコードは、Javaにおけるカプセル化の基本的な実装を示しています:

  • プライベートフィールド: クラス外部からの直接アクセスを防ぎます。
  • パブリックなゲッターとセッター: フィールドへの制御されたアクセスを提供します。
  • 値の検証: セッターメソッド内で入力値を検証し、不適切な値の設定を防ぎます。

このアプローチにより、クラスの内部データを保護し、データの整合性を維持することができます。また、将来的にクラスの内部実装を変更する際にも、外部のコードに影響を与えずに変更を行うことができます。

Main.javaの解説

  • クラス定義
Java
public class Main {
    // ...
}

Main という名前の公開クラスを定義しています。

  • main メソッド
Java
public static void main(String[] args) {
    // ...
}

これはプログラムのエントリーポイントです。

  • Student オブジェクトの作成
Java
Student student1 = new Student("山田太郎", 20);
Student student2 = new Student("佐藤花子", 22);

Student クラスのコンストラクタを使用して、2つの Student オブジェクトを作成しています。

  • 学生情報の表示
Java
System.out.println("学生1の情報:");
displayStudentInfo(student1);

System.out.println("\n学生2の情報:");
displayStudentInfo(student2);

displayStudentInfo メソッドを呼び出して、各学生の情報を表示しています。

  • 学生情報の更新
Java
student1.setName("山田次郎");
student1.setAge(21);

System.out.println("\n更新後の学生1の情報:");
displayStudentInfo(student1);

setNamesetAge メソッドを使用して student1 の情報を更新し、再度表示しています。

  • 無効な年齢でのテスト
Java
student2.setAge(150);

無効な年齢を設定しようとしています。これは Student クラスの setAge メソッド内で処理されるはずです。

  • displayStudentInfo メソッド
Java
private static void displayStudentInfo(Student student) {
    System.out.println("名前: " + student.getName());
    System.out.println("年齢: " + student.getAge());
}

このプライベートメソッドは、Student オブジェクトの情報を表示するために使用されます。getNamegetAge メソッドを呼び出しています。

このコードは、Student クラスの使用例を示しています:

  • オブジェクトの作成と初期化
  • ゲッターメソッドを使用した情報の取得
  • セッターメソッドを使用した情報の更新
  • 無効なデータ(年齢)の処理

このコードは、オブジェクト指向プログラミングの基本的な概念(カプセル化、メソッドの使用)を実践しています。また、displayStudentInfo メソッドの使用は、コードの再利用性を高めています。

プログラム例2: 銀行口座の管理

BankAccount.java

Java
public class BankAccount {
    // privateフィールド
    private String accountNumber;
    private double balance;

    // コンストラクタ
    public BankAccount(String accountNumber, double initialBalance) {
        this.accountNumber = accountNumber;
        this.balance = initialBalance;
    }

    // 口座番号のゲッター
    public String getAccountNumber() {
        return accountNumber;
    }

    // 残高のゲッター
    public double getBalance() {
        return balance;
    }

    // 入金メソッド
    public void deposit(double amount) {
        if (amount > 0) {
            balance += amount;
            System.out.println(amount + "円入金しました。");
        } else {
            System.out.println("無効な入金額です。");
        }
    }

    // 出金メソッド
    public void withdraw(double amount) {
        if (amount > 0 && balance >= amount) {
            balance -= amount;
            System.out.println(amount + "円出金しました。");
        } else {
            System.out.println("出金できません。");
        }
    }
}

Main.java

Java
public class Main {
    public static void main(String[] args) {
        // BankAccountオブジェクトの作成
        BankAccount account1 = new BankAccount("1234-5678", 10000);
        BankAccount account2 = new BankAccount("8765-4321", 20000);

        // 口座情報の表示
        System.out.println("口座1の情報:");
        displayAccountInfo(account1);

        System.out.println("\n口座2の情報:");
        displayAccountInfo(account2);

        // 入金と出金の操作
        System.out.println("\n口座1での操作:");
        account1.deposit(5000);
        account1.withdraw(2000);
        account1.withdraw(20000); // 残高不足のケース

        System.out.println("\n操作後の口座1の情報:");
        displayAccountInfo(account1);

        System.out.println("\n口座2での操作:");
        account2.deposit(-1000); // 無効な入金額のケース
        account2.deposit(10000);
        account2.withdraw(5000);

        System.out.println("\n操作後の口座2の情報:");
        displayAccountInfo(account2);
    }

    // 口座情報を表示するメソッド
    private static void displayAccountInfo(BankAccount account) {
        System.out.println("口座番号: " + account.getAccountNumber());
        System.out.println("残高: " + account.getBalance() + "円");
    }
}

出力結果:

口座1の情報:
口座番号: 1234-5678
残高: 10000.0円

口座2の情報:
口座番号: 8765-4321
残高: 20000.0円

口座1での操作:
5000.0円入金しました。
2000.0円出金しました。
出金できません。

操作後の口座1の情報:
口座番号: 1234-5678
残高: 13000.0円

口座2での操作:
無効な入金額です。
10000.0円入金しました。
5000.0円出金しました。

操作後の口座2の情報:
口座番号: 8765-4321
残高: 25000.0円

BankAccount.javaの解説

  • クラス定義
Java
public class BankAccount {
    // ...
}

BankAccount という名前の公開クラスを定義しています。

  • プライベートフィールド
Java
private String accountNumber;
private double balance;

クラス内でprivateキーワードを使用して、accountNumberbalanceフィールドを定義しています。これらのフィールドは直接外部からアクセスできません。

  • コンストラクタ
Java
public BankAccount(String accountNumber, double initialBalance) {
    this.accountNumber = accountNumber;
    this.balance = initialBalance;
}

BankAccountクラスのコンストラクタを定義しています。口座番号と初期残高を受け取り、フィールドを初期化します。

  • 口座番号のゲッター
Java
public String getAccountNumber() {
    return accountNumber;
}

accountNumberフィールドの値を取得するためのゲッターメソッドです。

  • 残高のゲッター
Java
public double getBalance() {
    return balance;
}

balanceフィールドの値を取得するためのゲッターメソッドです。

  • 入金メソッド
Java
public void deposit(double amount) {
    if (amount > 0) {
        balance += amount;
        System.out.println(amount + "円入金しました。");
    } else {
        System.out.println("無効な入金額です。");
    }
}

このメソッドは入金処理を行います。入金額が正の値である場合のみ残高を更新し、そうでない場合はエラーメッセージを表示します。

  • 出金メソッド
Java
public void withdraw(double amount) {
    if (amount > 0 && balance >= amount) {
        balance -= amount;
        System.out.println(amount + "円出金しました。");
    } else {
        System.out.println("出金できません。");
    }
}

このメソッドは出金処理を行います。出金額が正の値で、かつ残高が十分にある場合のみ残高を更新し、そうでない場合はエラーメッセージを表示します。

このコードは、銀行口座を模したクラスの基本的な実装を示しています:

  • カプセル化: プライベートフィールドとパブリックメソッドを使用してデータを保護しています。
  • データの整合性: 入金と出金メソッドで値のチェックを行い、不正な操作を防いでいます。
  • 情報の隠蔽: 残高の直接操作はできず、適切なメソッドを通してのみ変更可能です。

このアプローチにより、銀行口座の基本的な機能を安全に実装し、不正な操作や誤った状態の発生を防ぐことができます。また、将来的に追加機能(例:利息計算、取引履歴など)を実装する際にも、既存のコードに影響を与えずに拡張することができます。

Main.javaの解説

  • クラス定義
Java
public class Main {
    // ...
}

Main という名前の公開クラスを定義しています。

  • main メソッド
Java
public static void main(String[] args) {
    // ...
}

これはプログラムのエントリーポイントです。

  • BankAccount オブジェクトの作成
Java
BankAccount account1 = new BankAccount("1234-5678", 10000);
BankAccount account2 = new BankAccount("8765-4321", 20000);

BankAccount クラスのコンストラクタを使用して、2つの口座オブジェクトを作成しています。

  • 口座情報の表示
Java
System.out.println("口座1の情報:");
displayAccountInfo(account1);

System.out.println("\n口座2の情報:");
displayAccountInfo(account2);

displayAccountInfo メソッドを呼び出して、各口座の情報を表示しています。

  • 入金と出金の操作
Java
System.out.println("\n口座1での操作:");
account1.deposit(5000);
account1.withdraw(2000);
account1.withdraw(20000); // 残高不足のケース

System.out.println("\n口座2での操作:");
account2.deposit(-1000); // 無効な入金額のケース
account2.deposit(10000);
account2.withdraw(5000);

各口座に対して入金出金の操作を行っています。意図的に無効な操作(残高不足の出金、負の入金額)も含めています。

  • 操作後の口座情報表示
Java
System.out.println("\n操作後の口座1の情報:");
displayAccountInfo(account1);

System.out.println("\n操作後の口座2の情報:");
displayAccountInfo(account2);

操作後の各口座の情報を再度表示しています。

  • displayAccountInfo メソッド
Java
private static void displayAccountInfo(BankAccount account) {
    System.out.println("口座番号: " + account.getAccountNumber());
    System.out.println("残高: " + account.getBalance() + "円");
}

このプライベートメソッドは、BankAccount オブジェクトの情報を表示するために使用されます。getAccountNumbergetBalance メソッドを呼び出しています。

このコードは、BankAccount クラスの使用例を示しています:

  • オブジェクトの作成と初期化
  • ゲッターメソッドを使用した情報の取得
  • 入金(deposit)と出金(withdraw)メソッドの使用
  • 無効な操作(残高不足の出金、負の入金額)のテスト

このコードは、オブジェクト指向プログラミングの基本的な概念(カプセル化、メソッドの使用)を実践しています。また、displayAccountInfo メソッドの使用は、コードの再利用性を高めています。このプログラムは、BankAccount クラスの機能が正しく動作していることを確認するためのテストケースとしても機能しています。

まとめ

  • カプセル化は、データ(属性)と、そのデータを操作するメソッド(振る舞い)を一つのユニット(クラス)にまとめる概念です。
  • プログラム例では、アクセス修飾子ゲッターとセッターを使用して、情報をカプセル化し、不正な操作を防いでいます。
  • カプセル化により、データの整合性が保たれ、オブジェクトの状態を制御することが可能になります。

カプセル化を適切に実装することで、より安全で保守性の高いコードを作成することができます。これは特に大規模なプロジェクトや長期的なメンテナンスが必要なシステムにおいて重要です。プログラマーはカプセル化の概念を十分に理解し、適切に適用することで、より堅牢で拡張性のあるソフトウェアを設計することができます。

未経験でもWEBスキルを取得したい方
  • Javaコース
    Javaプログラミングを基礎から応用まで、体系的に学べる実践的なカリキュラムが特徴です。「マインクラフト」を通じてJavaの基本文法とフレームワークの概念を学びます。また、実際のプロジェクト開発を通じて、データベース連携やWebアプリケーション開発のスキルを身につけることができます。

コメント

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