【イメージつき】オブジェクト指向についてまとめてみた～継承・抽象・インターフェースって何？～

# **概要**
この投稿の構成をツリーにあらわしました。

1. **はじめに**
2. **オブジェクト指向（ＯＯＰ）とは**
3. **「責任」という観点から見たＯＯＰと非ＯＯＰ**
	1. ＯＯＰの責任
	2. 非ＯＯＰの責任
4. **オブジェクト指向特有の概念**
	1. カプセル化
	2. 継承
	3. 抽象
	4. インターフェース
5. **色々な違いを比較する**
	1. 集約と継承の違い
	2. 継承と抽象とインターフェイスの違い
	3. virtualとabstractの違い

# **はじめに**
<details><summary>初投稿ということで、簡単に経緯・目的を説明します。</summary>
これまで、ブランク有りで3年ほどJavaやvb.netなどのオブジェクト指向の言語にふれてきました。
オブジェクト指向を理解できてますか？と聞かれると、**自信無し**の状態。
そんな状態のまま、新たな職場でC#を扱うことになりさあ大変。
オブジェクト指向への理解へ向け、気持ち新たに意気揚々と勉強を開始しました･･･**が、しょっぱなで躓きました！**
あれこれ情報収集するも「そもそも」がわからない状態。
いくら手段を覚えたところで、**『なぜそれが必要なのか』**というナゾループに陥ってしまい、説明がぜんぜん頭に入ってこない。
それでも、あれやこれやとひっしのぱっちで勉強すること4日が経過しました。
至らぬところも多々あると思いますが、現在の**なんとかここまで来た**という状況を記録します。</details>

読み飛ばしてもらっても大丈夫です！

# **オブジェクト指向（ＯＯＰ）とは**
ＯＯＰとは**オブジェクト指向プログラミング（OOP：object-oriented programming）**の略。
ＯＯＰの考え方に、クラスという考え方がある。
**クラス**は、状態をあらわす**「フィールド」**と、ふるまいをあらわす**「メソッド」**をメンバとして構成される。
![2018-02-20 22.29.41.jpg](https://qiita-image-store.s3.amazonaws.com/0/236637/b3c99c99-4710-9885-94cf-bf99d6574451.jpeg)

これらはクラス内で扱われるため、管理が一元化できるというメリットがある。
「事象を擬人化する」プログラム。

**クラスは設計書**であり、それを**実体化したものがオブジェクト**という。
![2018-02-20 22.30.25.jpg](https://qiita-image-store.s3.amazonaws.com/0/236637/d2bde8bd-bdf4-9543-8b6d-b499df434023.jpeg)


ＯＯＰの反対は、非ＯＯＰと呼ぶ。
ＯＯＰは、**関数型**や**手続き型**と並べられて比較されることが多い。


# **「責任」という観点から見たＯＯＰと非ＯＯＰ**
[岩谷 和男さんの投稿記事](https://www.gixo.jp/author/iwatani/)が私にはビンゴで、参考にさせて頂きました。
ポイントを抜粋してメモします。
## **ＯＯＰの責任**
クラスの情報を、オブジェクト（またはインスタンス？）の**生成から消滅まで保持し続けて、呼び出し元からの求めに応じて値を返却する**、という責任を持つ
## **非ＯＯＰの責任**
非OOPのプログラムは単純に「入力パラメータを受け取って出力結果を返す」という手続きの集合体。
クラスに所属する属性や処理という位置づけはなく、**単に都度呼ばれる単発の関数**のようなイメージ。

# **オブジェクト指向特有の概念**
## **カプセル化**
#### 目的
- 他クラスから、自クラスのメンバ状態（フィールド）や振る舞い（メソッド）を**隠蔽**することで、クラスに含まれる状態や動作などの内容を**意識せず**に、使うことができる。
- 外部からの**不必要な操作を制限**することで、自由気ままにオブジェクトのフィールドの値を変えたり、メソッドを利用できないようにする。
- **色々見えすぎたら混乱**するので、必要なものだけ見せるようにしている。

#### 概要
- 必要最低限のメンバだけをpublicで公開し、そのほかのメンバをprivateで非公開にすることで、プログラムの**保守性（改造しやすさ）**を向上させることができる。
- そのほか、**目的に合わせて**アクセス修飾子を指定することができる。

## **継承**
#### 目的
- 親クラスのメンバ（フィールドとメソッド）を、**子クラスでも使える**ようにする。
- 親クラスの**本質的な機能**（または、階層構造において**共通化できる機能**）を、子クラスに受け継ぐことができる。
- 子クラス間で共通している機能を親に持たせて継承することで、**コード量を少なくする**ことができる。

#### 概要
- カテゴライズした際に、親子の関係をなすクラス間には「継承関係」があると言える。
- 単に、共通する振る舞いが多ければ継承関係があるというものでもないので、継承関係を指定する際には階層構造の見極めが必要となる。
- C＃の場合、単一継承はできるが、**多重継承はできない**ため、子クラスは複数の親クラスを指定できない。
- 親クラスのメンバをそのまま継承して使うこともできるし、子クラスで特有の動きや状態を保持する場合は、親のメンバをオーバーライドすることができる。

#### 代表するアクセス修飾子

|  親クラスの修飾子   |  子クラスの修飾子   |
|:------------------:|:------------------:|
|       **virtual**      |       **override**     |

## **抽象**
#### 目的
- 上位クラスでは実装を必要せず、下位クラスで特殊な動作が必要とされる場合に、抽象化クラスを継承させることで、具体的な動作は下位クラスに委ねることができる。

#### 概要
- ポリモーフィズム（多態性、多相性）を実現する手段の一つ。
- オーバーライドされることを前提としたクラスであり、**継承されて始めて**実態を持つ
- オーバーライドされることを前提のメンバだけでなく、**処理が実装されたメソッド**や、**状態を保持するフィールド**も含むことができる。
- 上位クラスの**アクセス修飾子abstract**が付く抽象メソッドは、下位クラス（具象クラス）で**必ず**定義・実装をしないと行けない。

#### 代表するアクセス修飾子

|  親クラスの修飾子   |  子クラスの修飾子   |
|:------------------:|:------------------:|
|       **abstract**      |       **override**     |

## **インターフェース**
#### 目的
- 新たにサブクラスを追加する際、そこに含まれるメンバーに関する**契約**や**約束事項**を決めておきたいときに、インターフェースを実装する。
- インターフェース（契約）を実装して作られたクラスには、**特定の機能が用意されている事**が保証され、**仕様が統一**されていることで使いやすくなる。


#### 概要
- ポリモーフィズム（多態性、多相性）を実現する手段の一つ。
- インターフェースは、継承するものではなく、**実装**するもの。
- インターフェースは、**処理内容を持たない抽象メソッドだけ**で構成されるクラスで、フィールドはメンバに含めることができない。
- インターフェースの役割は**「ふるまい」の共通化**であり、コードの再利用ではない。
- インターフェースクラスを実装するクラスに対して、メソッドの**実装強制**をしている。
- インターフェースへのメンバーを追加することで、ライブラリやそれを利用する全てのクラスに対して**破壊的な変更を発生させる足かせ**となっていることが、昨今、問題視されている。

# **色々な違いを比較する**
## **集約と継承の違い**
- 継承関係にあるかどうかは関係なく、他クラスの機能をより集め、自クラスでそのまま使いたいことを、**集約**という。
- 集約とは、他のクラスの既存の機能をそのまま利用すること。
- 継承とは、他のある特定のクラスの機能を追加し、既存のクラスを拡張すること。
- 継承をis-a関連、集約をhas-a関連と呼ぶ。

## **継承と抽象とインターフェイスの違い**
#### 継承
- 親子関係にあるクラスにおいて、親クラスのメンバを子クラスでも使うことができる。
- 親のメンバを継承することもできれば、子クラスでユニークなふるまいをするメンバで、親クラスのメンバをオーバーライド（上書き）することもできる。
- 上位クラスの修飾子：virtual、下位クラスの修飾子：override

#### 抽象
- 親子関係にあるクラスにおいて、親での実装したところで、子クラスのユニークなふるまいで完全にオーバーライドすることになる場合、上位クラスを抽象化させる。
- 実装を伴わないものだけでなく、実装を伴うメンバも含めることができる。
- 上位クラスの修飾子：abstract、下位クラスの修飾子：override

#### インターフェース
- フィールドはメンバに含めることができず、実装を伴わないメソッドのみをメンバとする。
- インターフェースを実装するクラスでは、その契約内容に含まれるメソッドの実装が強制される。
- 上位クラスの修飾子：interface

## **virtualとabstractの違い**
#### virtual
- 継承関係にあるクラス間において、親クラスのメソッドを継承する場合もあれば、子クラスで実装したメンバを優先して呼び出すという場合、親のメンバーにはアクセス修飾子virtualをつける必要がある。
- ただ、overrideのつけ忘れのために、意図せず親のメンバが呼び出されてしまう恐れがある。

#### abstract
- 親クラスのメンバーの実装が不要で、継承先の子クラスで個々にユニークな動作を必要とする場合、親クラスのメンバにアクセス修飾子abstractをつける。
- 親クラスでabstractがついたメンバは、サブクラスで必ず定義（及び実装）をしないと行けない。

# 最後に
最後までご精読頂きありがとうございました。
私と同じ境遇の方も多いはずではないでしょうか？（私の周りには、4、5人いました...）
文字に起こして再認識しましたが、まだまだ理解を深めていくところ、あまた。

何においても、設計の際に、**クラス間の階層構造や相関関係の分析を正しく行う**。
これに尽きるのではないかと思いました。

今回投稿した内容が、皆様の勉強のちょっとしたヒントになればとてもうれしいです。

内容に関して、ご認識や間違った解釈していましたら、お気軽にご指摘やアドバイスのコメントお待ちしております。

# 参考サイト・参考書籍
 [OOPと非OOPの違い｜オブジェクト指向プログラミング(OOP)をおさらいしよう（１）](https://www.gixo.jp/blog/4735/)
[JIS規格対応 標準C#入門 改訂第2版](https://www.amazon.co.jp/dp/B06Y129MYZ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)
[C#で始めるプログラミング 導入編 ](https://www.amazon.co.jp/%E3%81%A7%E5%A7%8B%E3%82%81%E3%82%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E5%B0%8E%E5%85%A5%E7%B7%A8-Microsoft-NET%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E3%82%AF%E3%83%A9%E3%82%A6%E3%82%B9-%E3%83%9F%E3%83%81%E3%82%A7%E3%83%AB%E3%82%BB%E3%83%B3/dp/4756141781/ref=sr_1_1?s=digital-text&ie=UTF8&qid=1518971552&sr=8-1&keywords=C%23%E3%81%A7%E5%A7%8B%E3%82%81%E3%82%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)
[C#で始めるプログラミング オブジェクト指向編](https://www.amazon.co.jp/%E3%81%A7%E5%A7%8B%E3%82%81%E3%82%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0-%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E6%8C%87%E5%90%91%E7%B7%A8-Microsoft-NET%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E3%82%AF%E3%83%A9%E3%82%A6%E3%82%B9-%E3%83%9F%E3%83%81%E3%82%A7%E3%83%AB%E3%82%BB%E3%83%B3/dp/475614179X/ref=sr_1_2?s=digital-text&ie=UTF8&qid=1518971552&sr=8-2&keywords=C%23%E3%81%A7%E5%A7%8B%E3%82%81%E3%82%8B%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0)
[インターフェースを「契約」として見たときの問題点](https://www.buildinsider.net/column/iwanaga-nobuyuki/013)