抽象クラスを使うメリット

#抽象クラスとは
抽象クラスとはクラスの一種で、次の特徴を持つ抽象的な概念です。

* 専ら**他のクラスに継承される**ことによって使用される。
* **インスタンスを持たない**。

抽象クラスのメンバ関数、メソッドを**仮想関数**と言います。すなわち抽象クラスはクラスの中でも上位概念にあるものを言います。

#具体例
割とよくある例ですが、ここでは```car```クラスと```motorcycle```クラスがあるとして、その基底クラスとして```vehicle```という抽象クラスを実装します。

「自動車」も「自動二輪車」も「乗り物」の一種で、発進と停止ができなければなりません。ですがそれぞれ発進も停止も方法が異なっています。なので、vehicleクラスでstartとstopを宣言し、carとmotorcycleでそれぞれ実装します。

##C++の例
C++では「=0となる仮想関数を持つものが抽象クラス」というようになっています。キーワードを使うわけではないので直感的ではありませんね。

またテスト部では、ポリモーフィズムを使うためにあえてポインタ変数で定義しています。別に実インスタンスとして呼び出しても構いません。

```c++:smp01.cpp
#include<iostream>
using std::cout;
using std::endl;

//抽象クラスvehicleの定義
class vehicle{
public:
   virtual void start(void)=0;
   virtual void stop(void)=0;
};

//vehicleを継承したクラスcarの定義
class car: public vehicle{
public:
   void start(void){
      cout << "car start" << endl;
   }
   void stop(void){
      cout << "car stop." << endl;
   }
};

//vehicleを継承したクラスmotorcycleの定義
class motorcycle: public vehicle{
public:
   void start(void){
      cout << "motorcycle start" << endl;
   }
   void stop(void){
      cout << "motorcycle stop." << endl;
   }
};

//テスト部
int main(void){
   vehicle* mycar;
   mycar = new car();
   (*mycar).start();
   (*mycar).stop();
   return 0;
}
```
##Pythonの例
Pythonでは```ABC```というライブラリを使います。

```python:smp02.py
from abc import ABCMeta
from abc import abstractmethod

#抽象クラスvehicleの定義
class vehicle(metaclass = ABCMeta):
   @abstractmethod
   def start(self):
      pass
   @abstractmethod
   def stop(self):
      pass

#vehicleを継承したクラスcarの定義
class car(vehicle):
   def start(self):
      print("car start.")
   def stop(self):
      print("car stop")

#vehicleを継承したクラスmotorcycleの定義
class motorcycle(vehicle):
   def start(self):
      print("moto start.")
   def stop(self):
      print("moto stop")

#テスト部
if __name__ == "__main__":
   mycar = car()
   mycar.start()
   mycar.stop()
```
##fortranの例
よく古典語扱いされるfortranでも、実は抽象クラスの定義や継承ができます。

https://qiita.com/Bluepost59/items/8d4b7d7713676fe06472

#メリット
## 多相性

抽象クラスを使うことでインスタンスのtypeによって挙動を変えるということができます。

C++ではポインタとしてインスタンスを定義したときに、その中身で呼ばれるメンバが自動的に変わります。例えばsmp01.cppのテスト部を```mycar=new motorcycle()```とすれば、下の実行部を変えることなくmotorcycleのstartとstopを呼び出すことができます。

pythonはそもそも動的型付けなのですが、smp02.pyで```mycar = motorcycle()```としてもきちんとmotorcycleのstartとstopが呼ばれて動きます。

##サブクラスの満たすべき要件を規定できる
そうはいっても「別に```typeof```とif分岐とかで処理すればいいんじゃないの」という気がします。しかも結局実装はサブクラスで行っているので、コーディング量が減るわけでもありません。pythonの例に至ってはvehicleを丸々カットしても何も動作は変わりません。そうなると抽象クラスを使うメリットはどこにあるのでしょう。

答えはサブクラスの持つべき要件を定められることにあります。抽象クラスを定めることで**サブクラスが持つべきメンバを定めることができます**。抽象クラスの持つメンバは必ずサブクラスでオーバーライドしなければいけません。<br>
```vehicle```の例に戻ります。仮に新しく```bicycle```クラスを作ったとしましょう。```bicycle```クラスを追加するにあたって、```vehicle```クラスで定義されているメンバ関数```start```、```stop```がすべて同じ形で実装されている必要があります。<br>
```vehicle```がなければ、```bicycle```を作る人は発進を```start```ではなく```depart```というメンバ関数で実装してしまうかもしれません。競輪が好きな人は```stop```を実装しないことさえあり得ます。

```cpp:smp03.cpp
class bycycle{
public:
   int depart(void);
};
```

そうとは知らず、インスタンスを使う人が```car```や```motocycle```と同じ感覚で```bicycle.start()```とすると、「そんなものはない」とコンパイルがはじかれます。

さらに困るのは「start」という同じ名前のメンバが違った引数や戻り値で書かれている場合です。今回はすべて同じファイルに書いているので大したことないように思えますが、実際は実装は分けて書いたりするのでそうなると大混乱です。

しかし、抽象クラスvehicleが定義されていれば、2つのメンバ関数```void start(void)```と```void stop(void)```がこの形で定義されていなければコンパイルが通りません。こうしてmainを実装する人は安心して発進と停止ができるわけです。

#まとめ
* 抽象クラスはクラスのメンバ、すなわち構造を定める。
* 抽象クラスを使えばポリモーフィズムを実装できる。

これらのメリットは**クラスを複数扱うような大規模なコード**で明らかになってきます。ポリモーフィズムが強調されているwebサイトやテキストが多いですが、個人的にはもう一つの役割の方が重要だと思います。

サンプルコード：https://gist.github.com/Bluepost59/79dbd90285d07c312a5326c4121cc86a