【わかりやすく解説‼】Javaのカプセル化の使い方

## 1.事前知識
- [【最新】UbuntuでJavaの環境を構築する方法](https://qiita.com/ryome/items/37c53e9638a9c6ea146a)

- [【初心者でもできる‼】Windows10にJava環境を作る方法（JDK14.0.1）](https://qiita.com/ryome/items/30135570954e36196821)

- [【わかりやすく解説‼】Javaのインスタンスの使い方](https://qiita.com/ryome/items/62ba0d8395af6698053a)

- [【初心者でもできる‼】Windows10にEclipseをインストールする方法（Java環境構築）](https://qiita.com/ryome/items/b47c5acdaa52cffbec58)

事前知識として、上記リンクの内容が必要です。


## 2.カプセル化とは

- `カプセル化` とは、オブジェクトの属性と関連する操作をまとめて同じクラスに定義することである。
- `カプセル化` したクラスの属性には `アクセッサメソッド` を通してのみアクセスできる。
- 他のオブジェクトは、 `カプセル化` したクラスに `直接アクセスできない` ため、属性値が不用意に書き換えられるのを防ぐことができる。

## 3.基本的な書き方

```PHP:テストクラス
package パッケージ名;
public class メインクラス名{
    public static void main(String[] args) {
        // インスタンスの生成
        クラス名 変数名 = new クラス名();
        // setterに値を入れる
        変数名.setインスタンス変数名(実引数);
        // getterで入れた値の取得をする
        System.out.println(変数名.getインスタンス変数名());
    }
}

```

```PHP:カプセル化クラス

package パッケージ名;
class クラス名{
    // インスタンス変数の定義
    private 型名 変数名;

    // コンストラクタ（インスタンス生成時に実行される）
    クラス名(){
        初期化処理など
    }
    // setter
    void setインスタンス変数名(型名 引数名){
        this.変数名 = 引数名;
    }
    // getter
    型名 getインスタンス変数名(){
        return 変数名;
    }
}
```

- 基本的なカプセル化は上記のように記述します。

## 4.事前準備
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/866ce029-9f28-05d3-ab0b-5e7b0467aafa.png)
1. Eclipseを起動し、 `[ファイル(F)]→[新規(N)]→[Java プロジェクト]` を選択する。
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/f1c5cc3c-449f-a66a-caef-d5f681054041.png)
2. プロジェクト名に `Test1` と入力し、 `完了` ボタンをクリックする。
![03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/a98626bb-291e-6aa8-5d69-df243d1673ca.png)
3. `[ファイル(F)]→[新規(N)]→[クラス]` を選択する。　　　
![05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/d0382456-4dd1-7474-4fbf-79735739b62c.png)
4. パッケージと名前に `Test1` と入力し、 `完了` ボタンをクリックする。
![06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/deff58a6-dfe5-ec36-8a1c-e0d7d7c9833b.png)
5. `Test1.java` が作成されたことを確認する。
![07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/b8ab1f4a-3498-d921-76d8-33ced82086e1.png)
6. 3と同様の手順でパッケージに `Test1` と入力し、 名前に `TestCapsule` と入力し、 `完了` ボタンをクリックする。
![08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/f699ad52-e759-b96c-623d-f637e49ce37a.png)
7. `Test1.java` と `TestCapsule.java` が作成されれば成功。

## 5.記述例

```java:Test1.java
package Test1;
public class Test1 {
	public static void main(String[] args) {
        // インスタンスの生成
		TestCapsule tc = new TestCapsule();
        // setterに値を入れる
        tc.setHello("おはようございます");
        // getterで入れた値の取得をする
        System.out.println(tc.getHello());
    }
}
```

```java:TestCapsule.java
package Test1;
public class TestCapsule {
	// インスタンス変数の定義
    private String hello;

    // コンストラクタ（インスタンス生成時に実行される）
	public TestCapsule() {
		this.hello = "Hello";
	}
    // setter
    public void setHello(String hello) {
		this.hello = hello;
	}
	// getter
    public String getHello() {
		return hello;
	}
}
```

- 上記の文をコピーして、文字コードは `S-JIS` を指定し、ファイル名を `Test1.java` , `TestCapsule.java` で保存し、実行するとこうなります。↓↓　　　　　　　　　　　　　　　　　　　　　　　　　　
![09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/89c73cd5-c080-578a-bd55-4f5155b9a0e0.png)

## 6.カプセル化をする理由

- `カプセル化` の狙いは「`データを保護する`」ということです。
- もし、 `カプセル化` をしなかった場合、データを改ざんすることが容易になります。

### 例：受験者名と受験者の点数を入力して合否判定を出すシステム
- 100点満点のテストで60点以上が合格です。
- 名前と点数を入力して合格か不合格かを判定します。
- 上記のようなシステムを作る際に `カプセル化` をしなかった場合、下記のコードように予期しない点数の変更が行えてしまう。


```java:Test1.java
//受験者名と受験者の点数を管理するシステム
package Test1;
public class Test1 {
	public static void main(String[] args) {
        // インスタンスの生成
		TestCapsule tc1 = new TestCapsule("A",50);
		TestCapsule tc2 = new TestCapsule("B",60);

		//予期しない変数の変更
		tc1.score = 10000;
		tc2.score = -100;

		//合否の表示
		tc1.Result();
		tc2.Result();
    }
}
```

```java:TestCapsule.java
package Test1;
public class TestCapsule {
	// インスタンス変数の定義
	String name;
	int score;

	// コンストラクタ（インスタンス生成時に実行される）
	public TestCapsule(String name, int score) {
		this.name = name;
		//不正な点数の入力対策
		if(0 <= score && score <= 100) {
			//0以上100以下
			this.score = score;
		}else {
			//0未満または101以上
			this.score = 0;
		}
	}
	//合否判定メソッド
	void Result() {
		if(60 <= score) {
			//合格
			System.out.println(name+"さんは"+score+"点で合格です。");
		}else {
			//不合格
			System.out.println(name+"さんは"+score+"点で不合格です。");
		}
	}
}
```
- 上記の文をコピーして、先ほど作成した `Test1.java` , `TestCapsule.java` に上書き保存し、実行するとこうなります。↓↓
![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/6fe72314-fe9a-5078-8e4a-9491a3c88f05.png)


- 上記の例では、100点満点のテストなため、 `10000点` も `-100点` も存在しない。
- `カプセル化` は直接データの操作をさせずに、一度関数を通す状況を作ることで `不正なデータ操作を防ぐ` 役割を持っている。
- 上記の例の `TestCapsule.java` を `カプセル化` すると以下のようになる。

```java:Test1.java
//受験者名と受験者の点数を管理するシステム
package Test1;
public class Test1 {
	public static void main(String[] args) {
        // インスタンスの生成
		TestCapsule tc1 = new TestCapsule("A",50);
		TestCapsule tc2 = new TestCapsule("B",60);

		//予期しない変数の変更
		tc1.setScore(10000);
		tc2.setScore(-100);

		//合否の表示
		tc1.Result();
		tc2.Result();

    }
}
```

```java:TestCapsule.java
package Test1;
public class TestCapsule {
	// インスタンス変数の定義
	private String name;
	private int score;

	// setter
	public void setName(String name) {
		this.name = name;
	}
	// getter
	public String getName() {
		return name;
	}
	// setter
	public void setScore(int score) {
		//不正な点数の入力対策
		if(0 <= score && score <= 100) {
			//0以上100以下
			this.score = score;
		}
	}
	// getter
	public int getScore() {
		return score;
	}

	// コンストラクタ（インスタンス生成時に実行される）
	public TestCapsule(String name, int score) {
		this.name = name;
		//不正な点数の入力対策
		if(0 <= score && score <= 100) {
			//0以上100以下
			this.score = score;
		}else {
			//0未満または101以上
			this.score = 0;
		}
	}
	//合否判定メソッド
	void Result() {
		if(60 <= score) {
			//合格
			System.out.println(name+"さんは"+score+"点で合格です。");
		}else {
			//不合格
			System.out.println(name+"さんは"+score+"点で不合格です。");
		}
	}
}
```
- 上記の文をコピーして、先ほど保存した `Test1.java` , `TestCapsule.java` に上書き保存し、実行するとこうなります。↓↓　　　　　　　　　　　　
![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/449867/3a71e604-cdec-811b-68a7-878d0b253223.png)

## 7.GitHub
GitHubにソースコードを公開しています。

https://github.com/ryomeblog/qiita/tree/master/%E3%80%90%E3%82%8F%E3%81%8B%E3%82%8A%E3%82%84%E3%81%99%E3%81%8F%E8%A7%A3%E8%AA%AC%E2%80%BC%E3%80%91Java%E3%81%AE%E3%82%AB%E3%83%97%E3%82%BB%E3%83%AB%E5%8C%96%E3%81%AE%E4%BD%BF%E3%81%84%E6%96%B9/Test1


## 8.関連
- [【覚えておくと便利!!!】Eclipseにおけるコンストラクタとgetter/setterの簡易作成](https://qiita.com/ryome/items/6c487ccc0c39847cd55f)
- [【初心者でもできる‼】Javadocの書き方](https://qiita.com/ryome/items/4f2d5928c8aaf195f407)