【Java】オブジェクト指向

# ０．はじめに
Javaを大学で学んでおります。
概念や特徴を以下の文類に分けてまとめました。

##### 関連学習
[【Java】用語](https://qiita.com/AkihideKato/items/13ba72a0c61eabc540c3)
[【Java】メソッド・型](https://qiita.com/AkihideKato/items/753ad55b10b29f184b0f)
[【Java】オブジェクト指向](https://qiita.com/AkihideKato/items/3eb988a962774a409f52)	
[【Java】インスタンス・コンストラクタ](https://qiita.com/AkihideKato/items/78fc47812f4eccad03cf)
[【Java】例外処理](https://qiita.com/AkihideKato/items/b0840610fc553c57cf1d)
[【Java】注意点・ルール](https://qiita.com/AkihideKato/items/63402744493932e9f87b)
[【Java】コードの記述向上にむけて（個人用memo）](https://qiita.com/AkihideKato/items/33fd1400be6be2e25f5a)

# １．3大構成
オブジェクト指向は以下3点による構成がされる
- **``継承``**
- **``多様性``**
- **``カプセル化``**	

# ２．オブジェクト指向について
これまで学んだ文法や計算方法というのは車でいう設計書のようなもの
オブジェクト指向とは**どうすれば車を作り出すことができるのか**という考え方に則る

ゴールから逆算して考えるため、どうすれば正解にたどりつけるか
数字の``10``を``1``と``9``を使用する際は "足し算を使えばいい"といった
**正解を導き出すための思考**が必要

## そもそもオブジェクトとは
**クラスを実体化したものや仮想世界で活動するモノの総称**
データと手続きを一体化（カプセル化）して定義利用するものなど							

フィールドを参照しインスタンス（実体）を生成した場合
そのインスタンスそのもののことや、配列における本体のことを
オブジェクトと呼ばれる

### メリット		
現実世界のモノを仮想世界内でも忠実に再現することが可能
人間が内容を把握しやすくし開発ができるためラクをすることができる	

### 手続き型の違い		
手続きは一行ずつそれぞれ書いていき、何をしようかと試行錯誤を繰り返すが
オブジェクト指向は必要なものを抽出し構築をしていく
その必要な要素それぞれを連携させ設計図を書いていく	
リアルな設計処理実行をコード内でも実現すればいいという考え方

### オブジェクト指向と非オブジェクト指向			
明確な思想に基づいてクラスが設計される		
RPGを作成する場合は
- **勇者が必要**
- **敵が必要**
といったようにそれぞれのメソッドが味を出し現実の世界で動いていく	
非オブジェクト指向は都合でクラスが設計されていくだけである指向	

### オブジェクトだけ生成する方法もある	
オブジェクト生成だけでも実際は可能だが
クラスを生成しオブジェクトを生成した場合のメリットとして	
**オブジェクトを何度も生成をすることが可能となる**
１つのクラスを生成してからオブジェクト生成をしたほうが良い場合があるということ

### オブジェクトは曖昧な存在	
クラスのことをオブジェクトと指す場合もあるし
インスタンスというワードを使用する場合もある	
**``インスタンス：車で言う車体``**
あるクラスを基に作られた具体的なオブジェクトそのもの

**``オブジェクト：クラスを実体化したもの、仮想世界で活動するもの``**
データと手続きを一体化（カプセル化）して定義利用するものがオブジェクト

# ３．クラスとは
**設計書のようなもの**							
オブジェクトの集合体である		
**どのような属性や操作をもっているか記述するもの**
勇者と敵が戦うプログラムを作る場合、
両者共に作成をした場合**何かの指示がないと戦ったり動いたりすることができない**
そのため``Mainメソッド``を起動源として動かせて戦わせたりする
- **``１．Mainメソッドを最大クラス``**
- **``２．勇者クラス、敵クラスは登場人物のクラス``**
- **``３．Mainメソッドで指示を出し、勇者クラス、敵クラスで詳細を定義する``**	


### なぜクラスを定義するのか				
上記のオブジェクト生成におけるクラス生成とほぼ同等の理由

- **``クラスに基づいてインスタンスを生成できるようになる``**
- **``クラスから生まれたインスタンスを入れる変数の型が利用できるようになる``**		

車の部品から様々な車種を作るのと考えは一緒		
				
### クラス型とは	
クラスを定義することで利用になる型のこと			
				
### クラス型変数とは				
``Java``は元々``int,String``といったような型を標準で元々持っている			
``Hero型``を定義することで``Hero``という型が使えるようになる			
**このクラス型変数は識別をするために変数を用いる**
例えば``Heroクラス``で勇者を作り勇者が2人いたとした場合どちらがどの勇者か識別がつかなくなる			
そのためクラス変数の型にインスタンスを代入し識別をするのが主な用途

### クラスを利用する順番
##### １．クラスの変数を宣言
```java
Average student ;
```
``Averageクラス``の``変数student``を宣言
この時点では変数宣言のみであり実体は存在しない

##### ２．クラスの実体を生成
```java
student = new Average ();
```
``new演算子``を使用し``Averageクラス``の実体を生成する		

##### １，２を合わせて
```java
Average student = new Average() ;	
```
このように記述することで``変数student``を``Averageクラス``として使用することができる	
この生成したクラスの実体を**インスタンス**という

## メンバ
**クラスを構成するフィールドとメソッドのことをクラスのメンバという**
メンバへのアクセスは以下の記述でアクセスが可能
```java
変数名.フィールド名
```
例として``Averageクラス``に``mathフィールド``があるとする
```java
student.math
```
アクセスしたフィールドは変数として扱うことができる
```java
Average num = new Average();		
num.math = 150;		
num.science = 200;		
System.out.println( "数学の平均点数：" + num.math);		
System.out.println( "化学の平均点数：" + num.science);　//出力：数学の平均点数：150　化学の平均点数：200		
```

# ４．継承 ( extend )
**別のクラスのメソッドが使えるようにすること**	
``Heroクラス``を作った場合、次にさらに強い``SuperHeroクラス``を作りたいとする	
その際``Heroクラス``内のメソッドを再び``SuperHeroクラス``内に記述しなければならない	
そこで``Heroクラス``のメソッドを使えるようにすることを継承という	
記述方法はクラス定義の先頭部分に``extands``を記述	
```Java
//AはBを継承する
public class A extands B {...}	
```
### オーバーライド
**継承した先の``SuperHeroクラス``で引き継いだメソッドを上書きすること**	
継承元の``Heroクラス``内の``attack()``というメソッドがある場合
新たに継承先の``SuperHeroクラス``で``attack()``を使用したい場合などに用いる	
このように``SuperHeroクラス``の継承先で上書きすることで
継承して受け継いだものを変更することができる	
厳密にいうとオーバーライド後の継承元の``attack()``は消滅していない
呼び出しが届かないことから上書きされているように見えるだけである

### superメソッド
**子のインスタンスから親インスタンスへメソッドやフィールドがアクセスできる**
オーバーライドしている場合は元々あったメソッドやフィールドをどうしても使いたい場合がある
そんな時に使用するメソッドが``superメソッド``

### 高度な継承		
これまでの話をさらに抽象化し俯瞰で考えみると、	
始めに``Heroクラス``を作成し細かい設定を記述していた	
だが``Heroクラス``とは別に魔法使いの``wizardクラス``や
回復がメインの``僧侶クラス``といった多くのクラスが増えた場合に、
- **``①クラスを作る``**
- **``②クラス内にHPやnameのフィールドを作る``**	
と作る度に定義をしなければならない	
この手間を省くためHeroクラスに備わっていたものを全て持ち備えた``Characterクラス``という大元を作成し	
中身は自由に書き換えてクラスを作ってくださいという思想が**高度な継承**と言える

### 高度な継承による不具合
高度な継承をするにあたり
**``攻撃attackの初期値はどうしようか？``**
といった問題が起こる
そもそも攻撃を書かなければいいという対策もできる
必要な場合にオーバーライドするよう記述すればいいが
- **``①オーバーライドをうっかり書き忘れる``**
- **``②本当は何も攻撃をしないクラスじゃないのか..？いや攻撃値をオーバーライドで書くべなのか..？``**
といったようにコードを書く上で懸念も生じる
そして``charactarクラス``を``new``してしまうといった
- **``③意図しないnew``**
の可能性もある
未完成である``characterクラス``から実体を生成しては不完全のためよくない

### 不具合の解決
抽象メソッドとも言われる``abstractメソッド``を利用する	
```Java
public abstract void attack;
```
``{}``カギカッコ無しの記述を用いる
こうすることで**何をするか曖昧なメソッド**と認識することができる	

**``abstractクラス（抽象クラス）``**
**``abstractメソッド``があるクラスは``abstractクラス``にしなければならない**	
よって曖昧なメソッドに所属するクラスは必ず``abstractクラス``になる	
このようなクラスを**抽象クラス**という	
そして抽象クラスは``new``が禁止されているためエラーとなる
よって**高度な継承による不具合③は``abstarctクラス``にすることにより解決する**

# ５．多様性
**コンピュータにもざっくりとを教えるような考え方のこと**
ヒトはある車を乗ったら別の車も乗れて運転できる	
だがコンピュータは車それぞれを明確に別で考えてしまう	
このヒトの考え方をコンピュータにも捉えるようにしたのが多様性

``RPG``を題材としたコードを記述した場合、勇者を操作するための``Hero``クラスと
魔法使いを操作するための``Wizard``クラスを生成したとする
多様性（ざっくりと考える）を用いることで``Hero``と``Wizard``を同一に考えることができ、``HP回復``もまとめてできる		

### 多様性におけるメリット
人間が呼び出したものがそれぞれ独自のスタイルで呼び出されるため多様性と言われている				
- **``配列化が可能``**				
ざっくりとした分類にされているため			
``Hero``であっても``Wizard``であっても同じざっくりとしたグループ化にすることが可能			
そのため``Main``でそれぞれ``+=50``ずつ回復させたい場合			
```Java
Hero A += 50			
Wizard B += 50
```
といった面倒な記述をしなくても			
```Java
c[0] = new Hero();			
c[1] = new Wizar();			
```
としfor文で+50ずつそれぞれ加算すれば簡略化した文が可能となる		

- **``それぞれの出力が可能``**				
クラスごとに攻撃方法が異なるメソッドが存在した場合			
それぞれ独自の攻撃方法が出力される			
このような面からも多様性と名付けられている			
**``要約すると、同一視してまとめて処理できることがメリットである``**			

# ６．カプセル化
**制限できるようにすること**			
人間がコードを記述するためミスやメソッドを間違って使ってしまう場合がある	
そのために制限をかけることにより事前にバグを防げるのがカプセル化	
あるクラスが外部から直接触られないようメソッドという殻（カプセル）で
フィールドが保護されているようなことからカプセル化とも言われている

**private**を利用しメソッドを通して間接的にフィールドの処理を行うこと		
**private修飾子**		
外部からのアクセスを制限する修飾子	
制限すると使い勝手が悪いためカプセル化を行い利便性を測る	

### 制限レベル
制限レベルは4つあるがここでは
- **``privateプライベート``**
- **``publicパブリック``**
2つを理解する

他のクラスから変更されないようにするために``HPフィールド``を``プライベート``にしたい場合
```Java
private int hp;
```
と記述する
そうすることで誤った値を使用される心配がなくなる

## フィールドという限定的な場所
メソッドは処理が走った後は変更されることは無い
だが``attack``といったフィールドは値が変化するものであり
制限箇所を狭めフィールドを保護することが重要とされる

            
### フィールド
**車で言う``速度・メーカー``の部分**	
雛形を作成しているイメージ
前述した``RPG``を題材としたコード内においてクラスがある場合、
``HP``や``MP``などがメソッド内で活躍するデータとして扱われる
これをフィールドと呼ばれる
### 例
```java
public class Body{
    String name;
    double weigth;
}
```
``String型``の``neme``や``double型``の``weigth``それぞれフィールドになる

### フィールドには実体がない
そのためインスタンス生成をしなければ利用することができない
``new演算子``を使用する必要がある

### フィールドにアクセスする場合
ドット演算子を使用する
```java
変数名.フィールド名
```
			
---
##### 参考文献
[スッキリわかるJava入門 第3版](https://book.impress.co.jp/books/1119101083) 
著者：中山清喬 と国本大悟　発行所：株式会社インプレス