*抽象クラスとは
共通のメソッドを呼び出したときに、インスタンスによってそのメソッドの挙動を変えることができるといった、ポリモーフィズムを実装するためのクラスです。PythonではABCモジュール(Abstract Base Class)を使うことで抽象基底クラスを定義することができるようになります。
使い方を理解するために、簡単なサンプルを例にして実装して動きを確認してみました。
*環境
- MacOS
- Python 3.6.3
*参考
*Python3の環境構築
Python3がまだ入っていない場合はインストールします。$ brew install python3
python3の仮想環境を作成します。
virtualenv に
-p
オプションでバージョンを指定することができます。$ virtualenv -p python3 env1
$ source env1/bin/activate
(env1)$ python -V
Python 3.6.3
-p
オプションの代わりにPython3の場所を指定する方法でもできます。$ which python3
$ virtualenv --python==/usr/local/bin/python3 env1
*抽象基底クラスの作成
ABCを定義するために ABCMetaクラスを使います。また、メソッドに
@abstractmethod
アノテーションを付けることで、抽象メソッドを定義することができます。抽象メソッドに引数を持たせることはできますが、処理の内容を書くことはできません。
さらに、この抽象基底クラスはインスタンス化することはできません。
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def say(self):
pass
*継承クラスの作成
Animalクラスを継承したサブクラスを作成します。サブクラスでは、抽象クラスで定義した抽象メソッドを必ず実装する必要があります。
今回は
Dog
とCat
というサブクラスを作成してsay()
の挙動をそれぞれ変えています。class Dog(Animal):
def __init__(self, name):
self.name = name
def say(self):
print('Wan!Wan!{}!'.format(self.name))
class Cat(Animal):
def __init__(self, name):
self.name = name
def say(self):
print('Mya!Mya!{}!'.format(self.name))
全部実装した下記内容のファイルを実行してみます。
from abc import ABCMeta, abstractmethod
class Animal(metaclass=ABCMeta):
@abstractmethod
def say(self):
pass
class Dog(Animal):
def __init__(self, name):
self.name = name
def say(self):
print('Wan!Wan!{}!'.format(self.name))
class Cat(Animal):
def __init__(self, name):
self.name = name
def say(self):
print('Mya!Mya!{}!'.format(self.name))
if __name__ == '__main__':
dog = Dog('Pochi')
dog.say()
cat = Cat('Tama')
cat.say()
<実行結果>
Wan!Wan!Pochi!
Mya!Mya!Tama!
Dog と Cat で挙動を変えることができました。
*補足
def __init__(self):
self にはそのクラスのオブジェクトが入っていて、このクラスで
self.name = XXX
などといったプロパティを設定することができます。def __new__(cls):
*所感
抽象化をすることでコードの可読性も上がりますし、オブジェクト志向プログラミングをする際にこの抽象化は必要になるので、使い方をよく理解して必要な場面で実践していきたいと思います。Sign up here with your email
ConversionConversion EmoticonEmoticon