継承の基本

継承とは

既にあるクラスの機能を引き継いで、新しいクラスを作成する方法を継承(inheritance) といいます。元となるクラスのことをスーパークラスといい、引き継ぐ新しい子クラスをサブクラスといいます。サブクラスはスーパークラスのメソッドが引き継げます。

スーパークラスと

つぎの例はスーパークラス「Person」を継承して、サブクラス「Wizard」「Warrior」を定義したものです。スーパークラスの機能がそのままで、データを設定したり、新たに機能を追加できます。

  • サブクラスは、スーパークラスからプロパティやメソッドを引き継ぐ
  • サブクラスは、新たにプロパティやメソッドを定義できる
  • サブクラスは、スーパークラスのプロパティやメソッドを上書きできる

継承の方法

Pythonではスーパークラスを () で囲んで、継承します。

スーパークラス
class スーパークラス:
    # スーパークラスの定義
サブクラス
class サブクラス(スーパークラス):
    # サブクラスの定義

スーパークラス

スーパークラスを「Person」とします。

スーパークラス(親クラス)
class Person:
    name: str = ""
    job: str = ""
    hp: int = 0

    def walk(self, direction: str):
        message = f"{self.name} move to {direction}"
        print(message)

    def talk(self, person, message):
        message = f"{person.name}!{message}"
        print(message)

    def attack(self, person):
        damage = 5
        person.hp -= damage

サブクラス

サブクラス「Wizard」が、スーパークラス「Person」を継承します。このとき、サブクラスは何も実装してないため、passキーワードで空のブロックで定義します。

サブクラス(子クラス)
from models.Person import Person

class Wizard(Person):
	pass

super()

super() は、スーパークラスにアクセスするメソッドです。

super()

スーパークラス

class スーパークラス:
    def __init__(self, 引数):
        # 処理

サブクラス

class サブクラス(スーパークラス):
    def __init__(self):
        # スーパークラスのコンストラクタ実行
        super.__init__(引数)

サブクラスの作成

ファイル構成

samples/
├── main_app2.py
└── models/
    ├── Wizard.py
    ├── Warrior.py
    └── Person.py

スーパークラスの修正

プロパティ追加

「Person」クラスに「mp」「level」「exp」「attackPower」「defencePower」プロパティを追加します。

Person.py
class Person:
    name: str = ""
    job: str = ""
    hp: int = 0
    # プロパティ追加
    mp: int = 0
    level: int = 1
    exp: int = 0
    attackPower: int = 0
    deffencePower: int = 0

    ...

スーパークラスのコンストラクタ修正

スーパークラスのコンストラクタは、「name」だけ設定するように修正します。

Person.py
class Person:
    name: str = ""
    job: str = ""
    hp: int = 0
    mp: int = 0
    level: int = 1
    exp: int = 0
    attackPower: int = 0
    deffencePower: int = 0

    # コンストラクタ修正
    def __init__(self, name):
        self.name = name

ダメージ処理修正

attack() によるダメージ処理は、それぞれの「attackPower」「defencePower」プロパティによってで計算します。

Person.py
class Person:
    ...

    def attack(self, person):
        # ダメージ処理修正
    def attack(self, person):
        damage = self.attackPower - person.defencePower
        if damage > 0:
            person.hp -= damage

サブクラスの作成

Wizardクラス作成

「Wizard」クラスを作成し「models/Person」をインポートします。

from models.Person import Person

継承

サブクラス「Wizard」を定義し、スーパークラス「Person」を継承します。

from models.Person import Person

class Wizard(Person):

コンストラクタ追加

コンストラクタを追加します。このとき「name」プロパティを、スーパークラスのコンストラクタに代入して名前を決定します。

Wizard.java
from models.Person import Person

class Wizard(Person):
    # サブクラスのコンストラクタ
    def __init__(self, name):
        # スーパークラスのコンストラクタ実行
        super.__init__(name)

プロパティ設定

「Wizard」特有のプロパティを設定します。

Wizard.java
from models.Person import Person

class Wizard(Person):
    def __init__(self, name):
        super().__init__(name)
        self.job = "Wizard"
        self.hp = 30
        self.mp = 20
        self.attackPower = 4
        self.defencePower = 3

Warriorクラス作成

同様にサブクラス「Warrior」も作成します。

Warrior.java
from models.Person import Person

class Warrior(Person):
    def __init__(self, name):
        super().__init__(name)
        self.job = "Warrior"
        self.hp = 50
        self.mp = 0
        self.attackPower = 7
        self.defencePower = 3

サブクラスの利用

モデルインポート

メインプログラム「main_app2.py」を作成し、「Wizard」「Warrior」をインポートします。

main_app2.py
from models.Wizard import Wizard
from models.Warrior import Warrior

インスタンス生成

「Wizard」「Warrior」のインスタンスを生成します。

main_app2.py
from models.Wizard import Wizard
from models.Warrior import Warrior

wizard = Wizard("アリス", "wizard")
warrior = Warrior("ボブ", "warrior")

インスタンスメソッド実行

attack() メソッドを実行し、結果を表示します。

main_app2.py
from models.Wizard import Wizard
from models.Warrior import Warrior

wizard = Wizard("アリス")
warrior = Warrior("ボブ")

wizard.attack(warrior)

print(f"{wizard.name}が、{warrior.name}を攻撃!")
print(f"{wizard.name}のHP: {warrior.hp}")
結果
アリスが、ボブを攻撃!
アリスのHP: 49

複数のクラスインスタンス

「Person」とは別の系統の「Monster」クラス作成し、複数のクラスインスタンスで処理してみましょう。

ファイル構成

samples/
├── main_app3.py
└── models/
    ├── Monster.py
    ├── Wizard.py
    ├── Warrior.py
    └── Person.py

Monsterの作成

「Monster」クラスを別途作成し、「Person」クラスと同様のフィールドとメソッドを追加します。

Monster.py
class Monster:
    name: str = ""
    hp: int = 0
    mp: int = 0
    level: int = 1
    exp: int = 0
    attackPower: int = 0
    deffencePower: int = 0

    def __init__(self):
        self.name = "スライム"
        self.hp = 5
        self.mp = 0
        self.attackPower = 2
        self.defencePower = 1

    def attack(self, person):
        damage = self.attackPower - person.defencePower
        if damage > 0:
            person.hp -= damage

メインプログラム

メインプログラム「main_app3.py」を作成し、各モデルクラスをインポートします。

main_app3.py
from models.Wizard import Wizard
from models.Warrior import Warrior
from models.Monster import Monster

インスタンス生成

「Person」をスーパークラスとした「Wizard」「Warrior」と「Monster」クラスのインスタンスを生成します。

main_app3.py
from models.Wizard import Wizard
from models.Warrior import Warrior
from models.Monster import Monster

wizard = Wizard("アリス")
warrior = Warrior("ボブ")
monster = Monster()

インスタンスメソッド実行

attack() を実行して結果を表示します。

main_app3.py
from models.Wizard import Wizard
from models.Warrior import Warrior
from models.Monster import Monster

wizard = Wizard("アリス")
warrior = Warrior("ボブ")
monster = Monster()

wizard.attack(monster)
print(f"{wizard.name}が、{monster.name}を攻撃!")
print(f"{monster.name}のHP: {monster.hp}")

warrior.attack(monster)
print(f"{warrior.name}が、{monster.name}を攻撃!")
print(f"{monster.name}のHP: {monster.hp}")
結果
アリスが、スライムを攻撃!
スライムのHP: 2
ボブが、スライムを攻撃!
スライムのHP: -4

演習

問題1

つぎの「Animal」クラスをスーパークラスとして、サブクラス「Dog」と「Cat」を作成してみましょう。

Animal.py
class Animal:
    def __init__(self, name):
        self.type = ""
        self.name = name
        self.crying = ""

    def walk(self):
        message = self.name + "が歩いた"
        print(message)

    def cry(self):
        print(self.crying)

    def escape(self):
        message = self.name + "が逃げた"
        print(message)

問題2

作成した「Dog」「Cat」クラスを使って、メインプログラムで walk() メソッドを実行してみましょう。

問題3

作成した「Dog」「Cat」クラスを使って、メインプログラムで cry() メソッドを実行してみましょう。

Python超入門