カプセル化とは

プロパティの隠蔽化

カプセル化はオブジェクト指向プログラミングの3大要素の1つで、クラスのメンバ変数を外部から直接参照させない(隠蔽化)する仕組みです。

アクセサメソッド

カプセル化はメンバ変数(プロパティ)をもとに gettersetterメソッドで定義するアクセッサメソッドを利用します。

  • setter:「set + プロパティ名」で値を設定
  • getter:「get + プロパティ名」で値を取得

getter/setter メソッドの例

emailプロパティを getter / setterメソッドを定義した例です。

  // フィールド
  private String email; 

  //setter
  public void setEmail(String email) {
    this.email = email;
  }

  //getter
  public int getEmail() {
    return this.email;
  }

アクセサメソッドの作成

ファイル構成

 sns/
   ├── App.java
   └── entity
          └── User.java

プロパティ定義

Userクラスにprivateプロパティを定義します。

sns.entity.User.java
User.java
package sns.entity;

public class User {

	private String email;
	private String name;
	private String password;

}

VSCodeでは、メンバ変数(プロパティ)からアクセッサメソッドを自動生成できます。

Warning

定義したフィールドは利用されていないため、Warningになっています。

getter/setterの追加

フィールドの選択

「User」クラスでgetter/setterを追加したいフィールドを、すべて選択します。

クイックフィックス

マウスオーバーしてクイックフィックスを選択します。

ショートカットキーでもクイックフィックスできます。

OS ショートカットキー
Mac Cmd + .
Windows Ctrl + .

getter/setterの確認

getter / setterが自動生成されました。

sns.entity.User.java
package sns.entity;

public class User {

	private String email;
	private String name;
	private String password;

	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	
}

setterの利用

プロパティに直接設定

privateプロパティに、値を設定します。

sns.App.java
package sns;

import sns.entity.User;

public class App {

	public static void main(String[] args) {
		User user = new User();
        user.name = "東京 太郎";
        user.email = "[email protected]";
        user.password = "pass12345";
	}

}

コンパイルエラー

privateプロパティに直接アクセスできないため、コンパイルエラーになりました。

setterの利用

エラー部分をコメントアウトして、setterでデータを設定してみましょう。

メインプログラム
sns.App.java
	public static void main(String[] args) {
		User user = new User();
//        user.name = "東京 太郎";
//        user.email = "[email protected]";
//        user.password = "pass12345";

        user.setName("東京 太郎");
        user.setEmail("[email protected]");
        user.setPassword("pass12345");
	}

getter

プロパティを直接取得

privateプロパティに直接アクセスします。

	public static void main(String[] args) {
		...
        
        System.out.println(user.name);
        System.out.println(user.email);
        System.out.println(user.password);
	}

コンパイルエラー

コンパイルエラーになりました。

getterの利用

プロパティに直接設定

privateプロパティに、値を設定します。

App.java
	public static void main(String[] args) {
        ....

        System.out.println(user.getName());
        System.out.println(user.getEmail());
        System.out.println(user.getPassword());
	}

getterでデータが取得できました。

結果
東京 太郎
[email protected]
pass12345

演習

問題1

price プロパティの setterメソッドの定義で正しいのはどれですか?

1.

public void setPrice() {
    this.price = price;
}

2.

public void setPrice(int price) {
    this.price = price;
}

3.

public int setPrice() {
    return this.price;
}

4.

public int setPrice(int price) {
    return this.price;
}

問題2

price プロパティの getterメソッドの正しいのはどれですか?

1.

public void getPrice() {
    this.price = price;
}

2.

public void getPrice(int price) {
    this.price = price;
}

3.

public int getPrice() {
    return this.price;
}

4.

public int getPrice(int price) {
    return this.price;
}

問題3

price プロパティの setter によるデータ設定で正しいのはどれですか?

  1. item.getPrice();
  2. item.setPrice();
  3. item.getPrice(300);
  4. item.setPrice(300);

問題4

price プロパティの getter によるデータ取得で正しいのはどれですか?

  1. item.getPrice();
  2. item.setPrice();
  3. item.getPrice(300);
  4. item.setPrice(300);

問題5

「Character」クラスで、setter/getterを実装し、コンパイルエラーが発生した箇所を修正してみましょう。