1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Pythonの多重継承を学んだ

Posted at

継承

定義済みのClassのプロパティやメソッドを引き継いでClassを作る仕組みです

1. メソッドについて

以下のようなclassを定義して継承してみます

継承元クラス
class A:
    def __init__(self, value):
        self.set(value)

    def get(self):
        return self.value

    def set(self, value):
        self.value = value

a = A(1)
a.get()  # 1が得られます

1-1. そのまま継承する

上で定義したclassをそのまま継承してclassを作ると以下のようになります
意味がないので実際に使うことはないと思いますがこれが最小構成です

特に何も加えずに継承する
class B(A):
    pass

b = B(1)
b.get()  # 1が得られます

1-2. メソッドをoverrideする

通常は以下のように既にあるメソッドを書き換えて作成すると思います

setメソッドをoverrideする
class C1(A):
    def set(self, value):
        self.value = value * 2

c1 = C1(1)
c1.get()  # 2が得られます

1-3. メソッドを追加する

存在しないメソッドを新たに追加して継承することもできます。これをやるとポリモーフィズムが崩れるのでオブジェクト指向だと非推奨な書き方だと思いますが、書けばその通り動きます

setメソッドをoverrideする
class C2(C1):
    def get_double(self):
        return self.value * 3

c2 = C2(1)
c2.get()  # 6が得られます

2. __init__とプロパティ

2-1. 親classの__init__メソッドを引き継ぐ

init__メソッド内でsuper().init()を呼ぶと、親classの__init()を呼び出すことができます。親classの__init__()内でもsuper()を読んでいれば親classの親classと順に辿っていけますので継承する場合はこちらで書くのが推奨されています

class D2(A):
    def __init__(self, value):
        super().__init__(value * 5)

d2 = D2(3)
d2.get()  # 15が得られます

2-2. __init__メソッドを新たに書く

単に書くこともできますが、継承元に既に書かれているものをこちらにも書いてしまうと修正時に複数個所の書き換えが必要になってしまいます。DRY原則から考えても完全に書き換える場合を除いてこの書き方はすべきでないと思います

class D1(A):
    def __init__(self, value):
        self.set(value * 5)

d1 = D1(2)
d1.get()  # 10が得られます

多重継承

複数のclassから継承することができます
同名のメソッドが存在する場合は先に指定された方が優先になります

1. メソッド継承の優先順位

継承元class
class E:
    def __init__(self, value):
        self.value = value
        
    def hoge(self):
        print('I am E: value is {}'.format(self.value))

e = E(3)
e.hoge()  # I am E: value is 3 が出力されます
継承元class
class F:
    def __init__(self, value):
        self.value = value * 2
        
    def hoge(self):
        print('I am F: value is {}'.format(self.value))

f = F(3)
f.hoge()  # I am F: value is 6 が出力されます

上記で定義した2つのclassを多重継承すると以下のようになります

Eを優先して継承する
class G1(E, F):
    pass

g1 = G1(3)
g1.hoge()  # I am E: value is 3
Fを優先して継承する
class G2(F, E):
    pass

g2 = G2(3)
g2.hoge()  # I am F: value is 6

メソッドである__init__とhogeが両方重複しているので、先に継承指定されている側だけが反映されています

2. 確認方法

上記ではprintで確認していましたが、classの__mro__で確認することができます

python
>>> print(G1.__mro__)  
(<class '__main__.G1'>, <class '__main__.E'>, <class '__main__.F'>, <class 'object'>)

3. 継承元classの数

継承は3つ以上のclassから実施することも出来ます
その場合も先に指定したものが優先されて継承となります

まとめ

多重継承なんていうとなんだか難しそうですが使い方自体は簡単ですn
レッツトライ

1
2
0

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
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?