40のおっさんのPython学習記録

20年以上前、学部の必修のC言語が全く理解できずに同級生に放り投げ、その後コーディングから遠ざかったガチ文系のおっさんが、ふと思い立ってPythonに挑戦しています。

新たな気づき(Chapter 12-2)

禿山で治水機能が低下したとしても杉なんか全部切り倒すべきだと思いませんか?おっさんは強くそう思っています。

  • スーパークラスAがあったとして、クラスAの機能を利用しつつも、クラスA自体に変更を加えたくない場合は新たなクラスBを作成し、クラスBからクラスAを読み込むことにより、クラスBではクラスAの機能に加えて新たな機能を実装できる。これを承継と言う模様。下の場合クラスAはBye!しか言えないけど、クラスBはByeもhelloも両方言える。クラスAにhelloを言おうとさせてもエラーになる。
>>> class A:
...     def bye(self):
...         print("Bye!")
...
>>> class B(A):             #スーパークラスとしてAを指定
...     def hello(self):
...         print("hello")
...
>>> obj=B()
>>> obj.hello()
hello
>>> obj.bye()
Bye!
>>> obj2=A()
>>> obj2.hello()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'A' object has no attribute 'hello' #クラスAにはhello機能はないよ
>>> obj2.bye()
Bye!
  • 外部ファイルのクラスをスーパークラスにすることも可能。from importで読み込めば良い。
from 外部ファイル import スーパークラス
class サブクラス(スーパークラス):
    以下サブクラス定義
  • スーパークラスのメソッドの一部を書き換えたい場合は、サブクラスからスーパークラスを呼び出した上で、同じ名前のメソッドを定義して上書きすることが推奨される。これをオーバーライドという。
#スーパークラス
class Greet():
    def hello(self):
        print("Hello!")
    def buy(Self):
        print("Bye!")

#サブクラス
class Greet2(Greet): #Greetをスーパークラスとして指定
    #スーパークラスのメソッドをオーバーライドする
    def hello(self, name=None): #スーパークラスと同じ名前のhelloを定義
        if name:
            print(name+"さんこんにちは!")
        else:
            super().hello() #スーパークラスのhello()をそのまま利用

obj1 = Greet2()
obj1.hello()      #nameに何も代入されなかったのでelse文が実行される
obj1.hello("井上") #nameの引数が指定されたのでif文が実行される。
#スーパークラス
class Person():
    def __init__(self, name, age):        #この初期化メソッドはサブクラスでは無効化される
        self.name=name
        self.age=age

#サブクラス
class Player(Person):
    def __init__(self, number, position): #最終的にこの初期化メソッドが生きる
        self.number=number
        self.position=position
  • また、サブクラスからスーパークラスの初期化メソッドを参照したい場合は、以下のように書く。
#スーパークラス
class Person():
    def __init__(self, name, age):
        self.name=name
        self.age=age

#サブクラス
class Player(Person):
    def __init__(self, name, age, number, position):
        super().__init__(name, age) #スーパークラスの初期化メソッドを呼び出す。selfは書かない
        self.number=number
        self.position=position