オブジェクト指向 上級

62. 抽象化と抽象クラス(abcモジュール)

抽象化とは

「抽象化」と聞くと難しそうですが、要は「共通の枠組みだけを先に決めておいて、細かい中身は後回しにする」という考え方です。たとえば「図形」というものを考えたとき、円にも四角にも三角にも「面積を求められる」という共通の性質がありますが、実際の計算方法(面積の求め方)はそれぞれまったく違います。このように「絶対に持つべき機能の名前だけ」を先に決めておき、具体的な中身は子クラスに任せる、という設計がよく使われます。

abcモジュールで「実装忘れ」を防ぐ

Pythonでは、標準ライブラリのabcモジュールを使うと、この考え方を厳密に表現できます。ABCを継承し、メソッドに@abstractmethodという飾り(デコレータ)を付けておくと、そのクラス自体を直接インスタンス化できなくなり、さらに子クラスがそのメソッドを実装していないと、エラーで教えてくれるようになります。「このメソッドは必ず子クラスで実装してください」という約束を、Pythonに守らせることができるわけです。

サンプルコード

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.14 * self.radius ** 2

circle = Circle(5)
print(circle.area())
Shapeクラスはareaメソッドを@abstractmethodとして宣言しているだけで、中身の実装はありません(passのみ)。そのためShape()と直接インスタンス化しようとするとTypeErrorになります。一方Circleクラスはareaメソッドをきちんと実装しているので、問題なくインスタンス化して使うことができます。

📝 練習問題

練習問題:Shapeを継承したSquareクラスを作り、1辺の長さを受け取ってareaメソッドで正方形の面積を計算できるようにしてください。