Python 抽象クラスの作り方

*抽象クラスとは

共通のメソッドを呼び出したときに、インスタンスによってそのメソッドの挙動を変えることができるといった、ポリモーフィズムを実装するためのクラスです。
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クラスを継承したサブクラスを作成します。
サブクラスでは、抽象クラスで定義した抽象メソッドを必ず実装する必要があります。
今回はDogCatというサブクラスを作成して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):
インスタンスが生成される前に呼び出されてインスタンス化をするメソッドです。cls にはクラスオブジェクトが入っています。


*所感

抽象化をすることでコードの可読性も上がりますし、オブジェクト志向プログラミングをする際にこの抽象化は必要になるので、使い方をよく理解して必要な場面で実践していきたいと思います。

Previous
Next Post »

人気の投稿