Python学習【365日チャレンジ!】84日目のマスターU(@Udemy11)です。
前にちらっとチャーシューを作った話をしましたが、実は料理好きなんです。
といってもたまにしか料理はしませんが、包丁にはこだわって、吉田金属工業のGlobalを使っています。
といっても、結構な値段がするので、1本しか持ってないんですけどね。。。
ホームベーカリーも持っていて、たまにパンを焼くので、今一番欲しいものは、Globalのパン切り包丁なんですが、「切れ味が悪くなったらどうやって研ぐんだろう?」と勝手に心配しています。
それではさっそくPython学習をはじめましょう!
昨日の復習
昨日は、ダックタイピングについて学習しました。
ダックタイピングは、クラスが違っても、同じ名前のメソッドがあれば、オブジェクトを切り替えて使えるということでした。
class Animal:
def voice(self, animal):
animal.voice()
class Duck:
def voice(self):
print('quack quack')
class Dog:
def voice(self):
print('Bow Bow')
duck = Duck()
dog = Dog()
mascot = Animal()
mascot.voice(duck)
mascot.voice(dog)
出力結果
quack quack
Bow Bow
昨日学習したコードとは違うコードを使ってみましたが、Animal
クラスから生成されたmascot
のメソッドであるvoice
の引数を変数animal
にしているので、17行目のmascot.voice(duck)
は、変数animal = duck
になり、duck.voice()
を実行することになります。
18行目も同様に、dog.voice()
を実行することになるので、アヒルの鳴き声と犬の鳴き声が出力されているということです。
このパターンでは、Duck
クラスでもDog
クラスでもvoice
メソッドが存在して、生成されたオブジェクトduck
とdog
を切り替えて、voice
メソッドを利用することができるということです。
詳しくは昨日の記事を参考にしてみてください。
それでは、本日の学習をすすめていきましょう!
抽象クラス
抽象クラスは、複数の継承クラスで同じメソッドを書く必要があるときに、ベース(親)クラスに「きちんとこのメソッドは継承クラスに入れてくださいね。入れないとエラーになりますよ」と記述しているクラスになります。
例えば、昨日学習したコードが次になりますが、ベースクラスでdrive
メソッドを指定しているので、継承クラスはそのdrive
メソッドを継承しています。
class Person(object):
def __init__(self, age=1):
self.age = age
def drive(self):
if self.age >= 18:
print("Yes! You can do it.")
else:
print("No! You can't drive.")
class Kids(Person):
def __init__(self, age=1):
if age < 18:
super().__init__(age)
else:
raise ValueError
class Adult(Person):
def __init__(self, age=18):
if age >= 18:
super().__init__(age)
else:
raise ValueError
ベースクラスのdrive
メソッドを切り分けて、次のように継承クラスに記述することもできます。
class Person(object):
def __init__(self, age=1):
self.age = age
class Kids(Person):
def __init__(self, age=1):
if age < 18:
super().__init__(age)
else:
raise ValueError
def drive(self):
print("No! You can't drive.")
class Adult(Person):
def __init__(self, age=18):
if age >= 18:
super().__init__(age)
else:
raise ValueError
def drive(self):
print("Yes! You can drive.")
この場合、Person
を継承するクラスに必ずdrive
メソッドを記述する必要があるので、記述を忘れるとエラーが起こってしまいます。
そのため、継承クラスがdrive
メソッドの記述がない場合にエラーを返すベースクラスを作ることができ、それが抽象クラスということです。
抽象クラスの記述方法
抽象クラスの記述方法は次のとおり
import abc
class Person(metaclass=abc.ABCMeta):
def __init__(self, age=1):
self.age = age
@abc.abstractmethod
def drive(self):
pass
コードが長くなるので、ベースクラスだけを抽出して記述しています。
@abc.abstractmethod
を使うことで、継承クラスのインスタンスを生成する際に、指定したメソッドが記述(実装)されていない場合はエラーが起こります。
一方で、抽象クラスを使わずに、継承クラスにメソッドが実装されていない場合は、インスタンスを生成する際にはエラーにならずに、メソッドを呼び出す際にエラーになります。
どの時点でエラーを返すかの違いで、基本にはどちらもエラーになるので、個人的にはあまり使う必要がないんじゃないかと思っちゃいました。
基本的にあまり使われない
Pythonはもともとこの抽象クラスという概念がなかったらしく、Javaで実行されていたので、アップデートの際にabc
モジュールとして標準ライブラリに加えられたという経緯があるとのことです。
なので、特に使う必要がないのなら、使わなくても問題なく、対応しなくても構わないというのが暗黙のルールでもあるようです。
複数人での開発がベース
最近になって気づいたのですが、このあたりの酒井さんの講座は、複数人でプログラムを書くことを前提の内容になっているので、一人で開発をすすめるにあたっては、ちょっと違和感を感じる部分があります。
つまり、わざわざそんなことする必要あるのかな?と思っちゃうわけです。
今後、自分のパッケージを配布するようになったり、チームでプログラムを書くようになった場合は、役立つスキルになるとは思うので、複数人で開発するための内容であると認識して学習しようと考えています。
酒井さんのPython講座は、Pythonの基礎基本から実践までを幅広く学びたい人には、おすすめの講座に間違いはありませんので、ぜひ一度受講されることをおすすめします。
それでは、明日もGood Python!