【Java】オブジェクト指向まとめ_その1

## この記事の趣旨
- 書いている人：プログラミング言語の基本文法がわかる､オブジェクト指向が分からない､エンジニア研修中
- Javaを学ぶ上で必要になってくるオブジェクト指向の考え方を覚える前に､**やんわりオブジェクト指向の世界観に腹落ちして理解を進めることがねらい｡**また､自分の知識の定着も兼ねて｡

## 背景
- Javaのセッションスコープの理解をする際にオブジェクト指向の周辺知識が必要になった｡
- 今まで避けていたこともあって､オブジェクト指向について改めて理解を深めようと考えた｡

## 参考になったもの
[初心者向けに徹底解説！オブジェクト指向とは？](https://eng-entrance.com/what-oop)
・オブジェクト指向周りの専門用語の理解に役立った｡

[オブジェクト指向のいろは \- Qiita](https://qiita.com/nrslib/items/73bf176147192c402049)
・抽象化の説明が､プログラミングやオブジェクト指向の背景を考える上で非常に役立った｡

[【Java】 コンストラクタって何？ this\( \)の意味 \| 一番かんたんなJava入門](https://nobuo-create.net/java-beginner-20/#i)
・今までのざっくりな知識(Javaの基礎)と抽象化をざっくり理解したあとに､この説明を読んだらとても身に入ってきました｡この説明のおかげでいろんなものが繋がってきました｡

[オブジェクト指向 \- Wikipedia](https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91)
・オブジェクト指向の6つの要約は､オブジェクト指向から脱線しないためのルールとして参考になりました｡

[オブジェクト指向超入門](http://www.rsch.tuis.ac.jp/~ohmi/software-intro/objectoriented.html)
・あとで､理解したかの理解度チェックに良さそうだったので忘備録｡

明解Java入門編
・オブジェクトとインスタンスの違いの理解に役立ちました｡


## オブジェクト指向の前に「抽象化」
いきなりですが､

「リンゴ」といえば何を思い浮かべますか？

...

「リンゴ」といえば､「赤くて丸くて食べられる物体」を､

を思い浮かべますよね｡

**具体的な情報がなくても理解することが出来た**と思います｡

これを**抽象化**といいます｡

例から察するに､**抽象化とは同じような特徴をグループ化して､それに対して適切な名前をつけています｡**

そして､プログラミングに関してもこれと同じことがいえると思います｡

プログラミングでも､同じような特徴を持ったグループがたくさん出てきます｡

その特徴に名前をつけたのが､変数であり､関数であり､オブジェクト指向です｡

これが､リンゴなら「赤くて丸くて食べられる物体」とすぐ説明がつきますが､プログラミングの場合は､抽象化されている対象がとても複雑でいろんなパターンがあるので理解するまでに時間がかかります｡

そして､オブジェクト指向もその複雑なものの一つです｡

ですが､今はいろんなパターンを知る必要はないので一つの王道パターンで**具体的な例をあげ､実際に抽象化してみて用語まわり**の理解を深めたいと思います｡

## オブジェクト指向の前に､「オブジェクト」とはなんだろう｡

~~オブジェクトとは､「物体」です｡~~

~~物体指向???~~

オブジェクトとは､一般的には「物体」ですが
プログラミングの世界では､「情報を持った集まり」「抽象化された対象」と捉えるほうが良いです｡

*2019/04/25 訂正しました｡以下､「物体」ではなく､「情報を持った集まり」「抽象化された対象」と読み替えてください｡*

## なぜ､オブジェクト指向?
現実世界では､ほとんどが「物体」で出来ています｡

「物体」とは､具体的な形を持って空間に存在するものとします｡

でも､すべてが「物体」では､分かりにくいのでそれぞれの特徴を分類して「物体」に名前をつけることにしました｡

**そう､抽象化です｡**

このように､**「現実世界と同じように物体と捉えたら扱いやすいよね」的な発想**を取り入れたのが**オブジェクト指向**としたほうが腹落ちするので､私はそのように理解しました｡

そして､この考え方をプログラミングにも適用したのがオブジェクト指向プログラミングです｡

これも**「だって､プログラミングの世界も現実世界と同じように考えた方がわかりやすいから」的な発想**からじゃないかと思います｡

## 現実世界で覚えるオブジェクト指向
オブジェクトは現実世界の物体を意味しているので､現実世界を例に覚えた方が分かりやすいと思ったので､**車を使って最小限の構成**で説明してみます｡

※最小限の構成とは､オブジェクト指向プログラミングのルールに則った構成です｡

## オブジェクト指向で主にやっていること
**車の設計書を作りました｡
車の設計書をもとに車を作ります｡**

簡単にいうと､以上です｡

さらにいえば､
**車をどういう仕様(色､機能､重量､価格)にするかを書いた「設計書」を作って､
「設計書」をもとに製造している｡**

それだけです｡

そして､**車ができたら､車を走らせます｡**

↓

主にやっていることは**『オブジェクトを作るための設計書を作り､オブジェクトを作って､オブジェクトを動かす｡』**

(自分は､この理解の仕方が一番腹落ちしました｡)

## もう少しプログラミングっぽく考えてみる
今回は､実際に赤色の車を作る工程を例にやってみたいと思います｡

プログラミングの世界では､上から順番にコードが読み込まれていきます｡

例えば､次のような文章(分かりやすいようにコードではなく文章にしています)があったときに､上から順に読み込まれます｡

**1. 設計書の名前を､『車』という名前にする｡
2. 設計書の内容に､『色は赤』､『名前はA』という車に関する情報を書く｡
3. 設計書の内容に､『発信ができる』､『停止ができる』という車に関する動作を書く｡
4. 『車の設計書』をもとに『車』を作る｡**

とすると､プログラミング上では『赤色のAという車』が出来上がります｡

このように､**『設計書』を作って､その中に『どんな物で』『どんなことができるか』を書いて､現実の物と同じように扱う考え方がオブジェクト指向プログラミングです｡**

でも､やっぱり車の色を『青色』にしたい場合もあると思います｡

その場合は､2の部分を『赤色』から『青色』に書き換えます｡

とすると､『青色のAという車』が出来上がります｡

プログラミングではこのように変更が容易にできます｡

現実世界では､これをしようとすると一度車を回収して､青色で上から塗って､返却するという工程を踏まないといけません(さらに､台数が多いとめちゃくちゃ大変です､俗にいうリコールです…)｡

でも､プログラミングの世界では､『車の設計書』の内容を書き換えるだけで済みます｡

なんとなく､オブジェクト指向の書き方がわかってきたかなと思います｡

## オブジェクト指向の専門用語(Java)を理解する
ざっくりですが､ここまでの意味が理解できれば

- オブジェクト指向
- オブジェクト
- クラス
- フィールド
- メソッド
- インスタンス
- インスタンス化

についても分かったも同然です｡

**これらの用語は､先程の例の一つひとつの出来事に対して名前をつけたに過ぎないからです｡**
(実際はもっと複雑ですが…自分が理解できるように簡単にしています｡)

- **オブジェクト指向 → 現実世界の物体と同じように扱う考え方**
- **オブジェクト → 物体の総称**(車)
- **クラス → 設計書の名前**(車の設計書)
- **フィールド → 物体の情報**(色は赤､名前はA)
- **メソッド → 物体の動作**(発信できる､停止できる)
- **インスタンス → 設計書をもとに作った物体**(車の設計書をもとに作った車)
- **インスタンス化 → 設計書をもとに物体を作ること**(車の設計書をもとに車を作ること)

やっぱり用語にすると難しいですが､やっていることは**『オブジェクトを作るための設計書を作り､オブジェクトを作って､オブジェクトを動かす｡』**です｡

## 用語の関係を図にしてみる
この関係を簡単に図にすると､こうなります｡
![オブジェクト指向_用語関連図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163887/e2c59ad4-adf3-65e9-b5e7-d4b17bc9b88c.png)


## オブジェクトとインスタンスの違い
オブジェクトとは､動的に生成される実体の総称
インスタンスはクラス型の動的に生成される実体の総称

図にすると､こんな感じです｡
![オブジェクト指向_オブジェクトとインスタンス.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163887/245dff2c-ac92-08f4-f9f8-271a97ea8e55.png)


ただ単に実体という意味の文脈で使われる場合は､オブジェクトもインスタンスどちらも同じ意味といえそうです｡

## 実際に､Javaのコードで書いてみる
### 1.設計書の名前を､『車』という名前にする｡

```java:Car.java
class Car {

}
```
【プログラムの解説】
・型はクラス型で「Car」というクラス名を宣言｡
・クラス型は､参照型に分類されます｡

### 2.設計書の内容に､『色は赤』､『名前はA』という車に関する情報を書く｡

```java:Car.java
class Car {
	String carname = "A"; // 車の名前
	String color = "red"; // 車の色
}
```

【プログラムの解説】
・車の名前を表すString型のcarname
・車の色を表すString型のcolor

### 3.設計書の内容に､『発信ができる』､『停止ができる』という車に関する動作を書く｡

```java:Car.java
class Car {
	String carname = "A"; // 車の名前
	String color = "red"; // 車の色

	void start() { // 車の発信動作
		System.out.println("発進します");
	}
 
	void stop() { // 車の停止動作
		System.out.println("止まります");
	}
}
```

【プログラムの解説】
・車の発信動作を表す｡値を返さない返却型のstartメソッド
・車の停止動作を表す｡値を返さない返却型のstopメソッド

### 4.『車の設計書』をもとに『車』を作る｡
```java:CarTest.java
class CarTest{
	public static void main(String[] args){
		Car car = new Car();
	}
}
```

【プログラムの解説】
・型はクラス型で「CarTest」というクラス名を宣言｡
・Car型の変数car(クラス型変数)に､new演算子でCarクラスをインスタンス化しオブジェクトを代入｡
→**作成したオブジェクトを代入してるようにみえますが､実際､変数CarはCarというオブジェクトを参照(見る)するだけです(アクセスする方法はその2で｡)**｡

図だとこんな感じかと｡
![クラス型変数.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/163887/37f7dccd-e9e4-51e7-f0a3-b63522090ad0.png)

ざっくりではありますが､オブジェクトを作るための設計書を作り､オブジェクトを作るところまでを色々参考にしながらまとめてみました｡

[【Java】オブジェクト指向まとめ\_その2 \- Qiita](https://qiita.com/snyt45/items/c0164e409d7f54501060)に続きます｡