[光-Hikari-のPython]09章-03クラス（継承）

###[【目次リンク】へ戻る](https://qiita.com/ko0821/items/379e8bd9e6ea01089419)
#[Python]09章-03 継承
前節では、クラスという設計図からインスタンス化によりオブジェクトを生成することについて触れました。
Bird型のオブジェクトのクラス図については以下の通りでした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/4ca56461-b251-d443-3399-7206f64160c7.png)


ところで、メソッドのところに注目すると、fly()とprint_status()の2つしかない状態です。実際に鳥（Bird）は鳴くので、今回この鳴く（cry）というメソッドを作成することを考えてみたいと思います。

しかし、「鳴く」といっても、鳥の鳴き方にはいろいろな種類があり、カラス（Crow）であれば「カァーカァー」、スズメ（Sparrow）であれば「チュンチュン」、鳩（Pegion）であれば「くるっぽー」などと多種多様です。
そうなると、鳥の種類ごとに以下のようにクラスを作らなくてはならなくなります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/57a28ca5-d5a5-9d4d-4c59-e005a8e06d37.png)


しかし、上記のクラス図を見てみると、いずれも**cry()メソッドの部分のみが異なっているだけ**であり、ほかの部分はすべてのクラス図では一致しています。

そこに注目して、その差分だけをプログラミングする方法を今回考えていきたいと思います。

##継承の機能
すでにあるクラスを利用して、少しだけ変更を加えてクラスを作成したいことがあります。この際に利用できるのが**継承（インヘリタンス）**です。

継承の機能を利用することで、すでにあるクラスの属性やメソッドを継承し、差分のみ属性やメソッドを書くだけでクラスを作成できます。

クラス図で表現すると以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/1754207f-a8b7-34b3-963f-a847d8b5965f.png)


Crowクラス、Pegionクラス、SparrowクラスはBirdクラスを継承していることがうかがえます。
この図からわかる通り、Birdクラスとは別にCrowクラス、Pegionクラス、Sparrowクラス**cry()**のみを指定すればよいことがわかります。
そうすれば、プログラムをいちいち書き直さず、必要な差分のみを追記するだけで済みます。

##継承でよく出てくる用語
上記の例で、BirdクラスをもとにCrowクラス、Pegionクラス、Sparrowクラスを作成しました。
この時、元となるクラス（今回はBirdクラス）のことを**スーパークラス**、継承して作られるクラス（今回はCrow、Pegion、Sparrowクラス）を**サブクラス**と言います。

次に、スーパークラスとサブクラスの関係に注目してみましょう。BirdとCrowの関係は、「Crow（カラス）はBird（鳥）です。」ということができます。
英語で表記すると、**「Crow is a Bird」**となります。こういった継承関係を**is_a関係**と言ったりします。

また、Bird（スーパークラス）から見るとCrow（サブクラス）に**特化**している、Crow（サブクラス）から見てBird（スーパークラス）に**汎化（はんか）**しているという表現をすることもあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/602679/ac18eb5b-2179-ff02-f656-79d317698ab2.png)


##スーパークラスとサブクラスを実装する
それでは実際にプログラムを書いてみましょう。
まず、継承のプログラムは一般に以下のように記載します。

```.py
class スーパークラス名:
    スーパークラスの属性
    スーパークラスのメソッドによる処理

class サブクラス名(スーパークラス名):
    サブクラスの属性
    サブクラスのメソッドによる処理
```

ただし、Crow、Pegion、Sparrowすべて書くと見づらくなるので、今回はCrowのみのサブクラスを書きます。
<font color="#00cccc">chap09</font>の中に<font color="#00cccc">samp09_03_01.py</font>に以下のコードを書いてください。

```.samp09_03_01.py
#スーパークラスの記載
class Bird:
    def __init__(self, name, color):
        print('-----インスタンス化したと同時にコンストラクタを呼び出します。-----')
        self.name = name
        self.color = color

    #飛ぶというメソッド
    def fly(self, m):
        print('-----flyメソッドを呼び出します。-----')
        print(f'バサバサと{self.name}は空を飛びます。')
        print(f'{m}mの高さを飛んでいます。')

    #インスタンス化したBirdのステータスを出力するメソッド
    def print_status(self):
        print('-----print_statusメソッドを呼び出します。-----')
        print(f'{self.color}色の鳥です。')


#サブクラスの記載
class Crow(Bird):
    def cry(self):
        print('-----サブクラスにあるcryメソッドを呼び出します。-----')
        print('カァーカァーと鳴きます。')


#サブクラスのCrowをインスタンス化する
kur = Crow('クロ助', '黒')

#サブクラスにあるcryメソッドを呼び出す
kur.cry()

#スーパークラスにあるflyメソッドを呼び出す
kur.fly(10)

#スーパークラスにあるprint_statusメソッドを呼び出す
kur.print_status()
```
><font color="#090" bgcolor="black">【実行結果】</font>
-----インスタンス化したと同時にコンストラクタを呼び出します。-----
-----サブクラスにあるcryメソッドを呼び出します。-----
カァーカァーと鳴きます。
-----flyメソッドを呼び出します。-----
バサバサとクロ助は空を飛びます。
10mの高さを飛んでいます。
-----print_statusメソッドを呼び出します。-----
黒色の鳥です。

まずは、サブクラスよりカラス（Crow）をインスタンス化し、**kur**に代入しています。
そして、サブクラス**Crow**にある、cryメソッドにより「カァーカァー」と鳴いているのを確認できます。

そして、注目してほしいのは、スーパークラスである**Bird**にあるメソッドも呼び出せていることです。
これは**Crow**クラスが**Bird**クラスを継承しているため、**Bird**クラスのメソッドも呼び出せるのです。

##最後に
継承はいろいろなライブラリでも登場することが多いのですが、ほかの言語であるJavaやC++でも登場する概念です。
継承でよく出てくる用語については基本情報技術者試験ではオブジェクト指向の分野では必ず出てくる用語ですので、押さえておきましょう。

###[【目次リンク】へ戻る](https://qiita.com/ko0821/items/379e8bd9e6ea01089419)