LoginSignup
1
3

More than 3 years have passed since last update.

【Python】オブジェクト指向プログラミング基礎vol.4~クラスの継承~

Posted at

継承(Inheritance)

既存のクラスが持つ変数とメソッドを引き継いで(継承して)、新しいクラスをつくる仕組み

class Diagonal:
    def __init__(self):
        self.name = 'Class Diagonal'

class Straight(Diagonal):
    pass

s = Straight()
print(s.name)

実行結果

Class Diagonal

実行すると、Class Diagonalという文字が表示される。Class Straightにはnameという変数宣言はないがDiagonalクラスで定義された変数にStraightクラスがアクセスできている。

class Straight(Diagonal)とクラス名の隣にかっこで他のクラス名を入れることで、上の場合だとStraightクラスはDiagonalクラスを継承するという意味になる。

継承元のクラス(Diagonalクラス)のことをスーパークラス(親クラス)といい、Straightクラスはサブクラス(子クラス)になる。

オブジェクトのデータメンバーとメソッドの一覧

あるオブジェクトのデータメンバーとメソッドのリストは、dir(オブジェクト)として取得できる。

print(dir(s))とすると下記のように出力され、オブジェクトStraightにnameがあることが確認できる。

['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'name']

メソッドの追加

子クラスで関数を追加することができる。子クラスからは、親クラスのメソッドも呼べる。

子クラスが親クラスの機能を含む。

class Diagonal:
    diag = "diagonal"

    def funcD(self):
        print('func D')


class Straight(Diagonal):  # DiagonalClassを継承
    def funcS(self):
        print('func S')

    def diag_print(self):
        print(self.diag)


s = Straight()
s.funcD()
s.funcS()
s.diag_print()

実行結果

func D
func S
diagonal

このように継承を用いると、継承元のクラスの変数とメソッドを継承先のクラスで利用できる。

既存のクラスを修正せずに機能追加が可能になり、保守性・再利用性が向上する

また継承は、クラスの共通部分を別クラスとしてまとめる仕組みともいうことができる。

以下の2つのクラスを見てみると、プログラムの内容に共通する部分が多いことがわかる。

class Soccer_player:
    def __init__(self, name):
        self.name = name

    def hello(self):
        print("私の名前は{}です".format(self.name))

    def shoot(self, field):
        print("{}で点を決めた".format(field))

class Baseball_player:
    def __init__(self, name):
        self.name = name

    def hello(self):
        print("私の名前は{}です".format(self.name))

    def home_run(self, field):
        print("{}でホームランを打った".format(field))

継承を使うとこのコードの共通部分をまとめることができる。

class Sports_player:
    def __init__(self, name):
        self.name = name

    def hello(self):
        print("私の名前は{}です".format(self.name))


class Soccer_player(Sports_player):
    def shoot(self, field):
        print("{}は{}で点を決めた".format(self.name,field))

class Baseball_player(Sports_player):
    def home_run(self, field):
        print("{}は{}でホームランを打った".format(self.name,field))


s = Soccer_player("クリステファン・ローディ")
b = Baseball_player("バーズ")
s.hello()
s.shoot("日産スタジアム")
b.hello()
b.home_run("東京ドーム")

実行結果

私の名前はクリステファン・ローディです
クリステファン・ローディは日産スタジアムで点を決めた
私の名前はバーズです
バーズは東京ドームでホームランを打った

Soccer_playerクラスとBaseball_playerクラスはSports_playerクラスを継承している。

2つのクラスの共通部分をSports_playerクラスにまとめた上で、Sports_playerクラスを敬称している

共通部分をまとめると、以下のようなメリットがある

  • プログラムの記述量が少なくなり、見通しが良くなる
  • 他のスポーツ選手のクラスを定義するのが簡単になる
  • 共通部分の変更が容易になる

共通部分をまとめることで、プログラムの保守性・再利用性を向上させている

オーバーライド(override)

継承では同じメソッドがあると、内容を上書きして差し替えることが可能。

class Diagonal:
    def hello(self):
        print('Hello Class Diagonal')

class Straight(Diagonal):
    def hello(self):
        print('Hello Class Straight')


s = Straight()
s.hello()

実行結果

Hello Class Straight

上のようにHello Class Straightと表示される。自分自身の定義が先で、なかったら親を探しにいく。親にもなければさらにその上へと探しに行く。

super関数

親クラスのメソッドに、子クラスからアクセスするときに使うのが、super関数

super().親クラスのメソッド(引数)のように記述する。

class Diagonal:
    def hello(self):
        print('Hello Class Diagonal')

class Straight(Diagonal):
    def hello(self):
        super().hello()
        print('Hello Class Straight')


s = Straight()
s.hello()

実行結果

Hello Class Diagonal
Hello Class Straight

上記の例だと、Diagonalクラスのhelloを呼び出してから、Straightクラスのhelloを呼び出している。

1
3
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3