趣味のPython・深層学習

中級者のための実装集

抽象クラスの基礎:Python abstractmethod

Pythonの抽象クラスについて

抽象クラスとは

抽象クラスとは、共通の機能を持つクラスのベースとなるクラスです。抽象クラスには実装されていないメソッドが含まれており、これらのメソッドは具象クラスで実装されなければなりません。 抽象クラスは、インスタンスを作成することはできません。具象クラスのインスタンスを作成する必要があります。 抽象クラスの役割は、クラスの設計を明確にすることと、共通のインターフェースを強制することです。

抽象クラスには、抽象メソッドと共通のメソッドが定義されています。 具象クラスは、抽象クラスを継承します。 具象クラスは、抽象メソッドを実装しなければなりません。 具象クラスは、共通のメソッドを継承しています。

抽象クラスの定義

Pythonでは、abcモジュールを使って抽象クラスを定義します。

import abc

class AbstractClass(abc.ABC):
    
    @abc.abstractmethod
    def abstract_method(self):
        """実装されていないメソッド"""
        pass
    
    def common_method(self):
        """共通のメソッド"""
        print("共通の処理")

abc.ABCを継承することで、クラスを抽象クラスにします。 @abc.abstractmethodデコレータを使うことで、メソッドを抽象メソッドにします。 抽象メソッドには、passだけが記述されています。

具象クラスの定義

具象クラスは、抽象クラスを継承し、抽象メソッドを実装します。

class ConcreteClass(AbstractClass):
    
    def abstract_method(self):
        """抽象メソッドの実装"""
        print("具象クラスの処理")

抽象クラスを継承します。 抽象メソッドをオーバーライドし、実装します。 共通のメソッドは継承されます。

抽象クラスの利点

抽象クラスには、以下のような利点があります。

コードの一貫性と整合性の向上

関連するクラスに共通のインターフェースを強制できます。 コードの保守性が向上します。

コードの再利用性の向上

共通の機能をベースクラスに集約できます。 重複コードを減らすことができます。

設計の明確化

クラスの設計が明確になります。 具象クラスがどのようなインターフェースを実装する必要があるかが明示的になります。

多態性の実現

抽象クラスのインスタンスではなく、具象クラスのインスタンスを使うことができます。 コードの柔軟性が高まります。

抽象クラスの注意点

抽象クラスを使う際には、以下の点に注意が必要です。

抽象メソッドのオーバーライド

具象クラスでは、抽象クラスの抽象メソッドをすべてオーバーライドする必要があります。 オーバーライドされていない場合は、TypeErrorが発生します。

インスタンス化の制限

抽象クラス自体はインスタンス化できません。 具象クラスのインスタンスを作成する必要があります。

継承の制限

抽象クラスを継承する場合、抽象クラスの抽象メソッドをすべてオーバーライドするか、 または継承したクラスも抽象クラスにする必要があります。

抽象クラスの例

ここでは、形状を表すクラスを例に、抽象クラスの利用例を示します。

import abc

class Shape(abc.ABC):
    """形状を表す抽象クラス"""
    
    @abc.abstractmethod
    def area(self):
        """面積を計算する抽象メソッド"""
        pass
    
    @abc.abstractmethod
    def perimeter(self):
        """周囲を計算する抽象メソッド"""
        pass
    
    def print_info(self):
        """形状の情報を出力するメソッド"""
        print(f"面積: {self.area()}")
        print(f"周囲: {self.perimeter()}")

class Rectangle(Shape):
    """長方形を表す具象クラス"""
    
    def __init__(self, width, height):
        self.width = width
        self.height = height
    
    def area(self):
        """長方形の面積を計算する"""
        return self.width * self.height
    
    def perimeter(self):
        """長方形の周囲を計算する"""
        return 2 * (self.width + self.height)

# 具象クラスのインスタンス化と使用
rectangle = Rectangle(5, 3)
rectangle.print_info()
出力:
Copy code面積: 15
周囲: 16

Shapeクラスは抽象クラスで、area()とperimeter()が抽象メソッドです。 Rectangleクラスは具象クラスで、Shapeクラスを継承しています。 Rectangleクラスでは、抽象メソッドをオーバーライドし、長方形の面積と周囲を計算する実装を行っています。 最後に、Rectangleクラスのインスタンスを作成し、print_info()メソッドを呼び出すことで、面積と周囲が出力されます。