抽象クラスとメソッド
CoddyのPythonジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 25/64。
抽象クラスとは、直接インスタンス化できず、サブクラスで実装しなければならない抽象メソッドを含むクラスです。
書式にたとえて考えてみましょう:抽象クラスは、必須項目(抽象メソッド)と任意項目(具象メソッド)がある、必ず記入しなければならない書式のようなものです。書式そのものを提出することはできず、まずすべての必須項目を記入しなければなりません。同様に、サブクラスですべての抽象メソッドが実装されるまでは、抽象クラスのインスタンスを作成できません。
抽象クラスを作成するには、abc モジュールをインポートします。
from abc import ABC, abstractmethod抽象メソッドを持つ抽象クラスを作成します。
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
def describe(self):
return "This is a shape" # 具象メソッド(実装がある)@abstractmethodデコレーターは、サブクラスで必ず実装しなければならないメソッドを示します。これらはフォームの「必須フィールド」です。describe()のような通常のメソッドには実装を持たせることができ、そのまま継承されます。これらは「事前入力済みフィールド」です。
抽象クラスを使う理由は? 抽象クラスは契約を強制します。Shape クラスを作るということは、「すべての図形は面積と周囲の長さを計算できなければならない」と宣言することです。これにより、重要なメソッドの実装を忘れてしまうことで発生するバグを防げます。
抽象クラスのインスタンスを作成してみましょう。
# これによりエラーが発生します:
# shape = Shape() # TypeError: 抽象クラスはインスタンス化できませんこのエラーは意図的なものです。空のフォームを送信しようとするようなものです。Pythonは「必須項目(areaメソッドとperimeterメソッド)がまだ入力されていません!」と言っています。
すべての抽象メソッドを実装する具象サブクラスを作成します。
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14 * self.radius ** 2
def perimeter(self):
return 2 * 3.14 * self.radiusこれで「必要なフィールドをすべて埋めた」ことになります。area()とperimeter()の両方を実装しました。Circleクラスは、インスタンス化できる完全な具象クラスになりました。
これで、具象クラスのインスタンスを作成できます。
circle = Circle(5)
print(circle.area())
print(circle.perimeter())
print(circle.describe()) # 継承された具象メソッド別の具象サブクラスを作成します。
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(4, 6)
print(rectangle.area())
print(rectangle.perimeter())出力:
78.5
31.400000000000002
This is a shape
24
20抽象クラスは、サブクラスが従うべき契約を定義します。ABCと@abstractmethodを使って抽象クラスを作成します。サブクラスはすべての抽象メソッドを実装する必要があり、そうしなければそのサブクラスも抽象クラスになります。これにより一貫性が保たれ、不完全な実装を防げます。
チャレンジ
中級このチャレンジでは、決済処理システムを実装します。
次のファイルの実装を完成させてください。
paymentmethod.py- 検証ロジックを備えた抽象基底クラスcreditcard.py- クレジットカード決済の実装paypal.py- PayPal決済の実装
各ファイルのTODOコメントに従って、必要な機能を実装してください。コメントに沿って、抽象メソッドの作成、具象サブクラスの実装、ファイル間の適切なインポート関係の設定を順を追って進められます。
driver.pyファイルには、さまざまな決済シナリオを処理し、それぞれの決済方法に応じた詳細を表示することで、実装が正しく動作するかを検証するテストケースが含まれています。
自分で試してみよう
from creditcard import CreditCard
from paypal import PayPal
# 実装をテストする - このテストコードは変更しないでください
cc = CreditCard("1234567890123456")
pp = PayPal("user@example.com")
# 有効な支払いを処理する
if cc.validate(100):
print(cc.process_payment(100))
print(cc.payment_details())
if pp.validate(200):
print(pp.process_payment(200))
print(pp.payment_details())
# 無効な金額を試す
if not pp.validate(0):
print("Invalid payment amount")
# コメントを解除すると、これはエラーになります:
# pm = PaymentMethod() # 抽象クラスはインスタンス化できないこのレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Pythonオンラインコンパイラ