抽象クラスとインターフェース

インターフェースの設計

抽象クラスの続きとして、今度は「インターフェース(Interface)」という考え方についてお話しするね。

インターフェースは、「これこれこういう機能は、必ず備わっていなければならないよ、という約束(ルール)だけをまとめたもの」だよ。まるで、ゲームのコントローラーのボタン配置の「設計図」みたいなものだね。

「Aボタンはジャンプ、Bボタンは攻撃」というルールがあれば、どんなに形や色の違うコントローラーでも、そのルールを守っていれば、同じゲームを遊ぶことができるよね。インターフェースも、プログラムの世界で似たような役割を果たすんだ。

Pythonには、他の言語にあるような「Interface」という特別なキーワードは無いけれど、抽象クラスを使ってインターフェースのような役割を持たせることができるんだ。つまり、すべてのメソッドが抽象メソッドである抽象クラスが、実質的にインターフェースとして機能するんだよ。

例を見てみよう。「動くことのできるもの」を表すインターフェースを考えてみようか。


# abcモジュールからABCとabstractmethodをインポートするよ
from abc import ABC, abstractmethod

# Movableという名前のインターフェースを作るよ(実質的な抽象クラス)
class Movable(ABC):
    # moveメソッドは抽象メソッドだよ。中身は書かない。
    @abstractmethod
    def move(self):
        pass

# CarクラスはMovableインターフェースを実装するよ(継承するよ)
class Car(Movable):
    def move(self):
        print("車が道路を走る!")

# AirplaneクラスもMovableインターフェースを実装するよ
class Airplane(Movable):
    def move(self):
        print("飛行機が空を飛ぶ!")

# BoatクラスもMovableインターフェースを実装するよ
class Boat(Movable):
    def move(self):
        print("ボートが海を進む!")

# いろんな「動くことのできるもの」をリストに入れて、動かしてみよう!
vehicles = [Car(), Airplane(), Boat()]

for v in vehicles:
    v.move()

# 出力:
# 車が道路を走る!
# 飛行機が空を飛ぶ!
# ボートが海を進む!

Movableクラスは、moveという抽象メソッドしか持っていないよね。これがインターフェースの役割なんだ。このMovableインターフェースを「実装」したクラス(CarAirplaneBoat)は、必ずmoveメソッドを自分たちで完成させなければならない、というルールが生まれるんだ。

こうすることで、どんな種類の「動くことのできるもの」でも、同じmove()という名前のメソッドを呼び出すだけで、それぞれの方法で動いてくれるようになる。これが、ポリモーフィズムの力も使った、インターフェースの設計だよ。

インターフェースをうまく使うと、プログラムの部品を組み合わせて作るときに、それぞれがどんな機能を「提供するのか」をはっきりと示せるから、もっと分かりやすくて、変更に強いプログラムを作れるようになるんだ!