추상 클래스와 메서드
Coddy Python 여정의 Object Oriented Programming 섹션에 포함된 레슨 — 64개 중 25번째.
추상 클래스는 직접 인스턴스화할 수 없으며, 하위 클래스에서 반드시 구현해야 하는 추상 메서드를 포함하는 클래스입니다.
양식(form)과 같다고 생각해보세요: 추상 클래스는 일부 필드는 필수(추상 메서드)이고 일부는 선택 사항(구체적인 메서드)인 필수 양식 코드와 같습니다. 양식 자체를 제출할 수는 없으며, 먼저 모든 필수 필드를 채워야 합니다. 마찬가지로, 하위 클래스에서 모든 추상 메서드가 구현될 때까지 추상 클래스의 인스턴스를 생성할 수 없습니다.
추상 클래스를 생성하기 위해 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: Can't instantiate abstract class이 에러는 의도된 것입니다 - 마치 빈 양식을 제출하려는 것과 같습니다. 파이썬은 "아직 필수 필드(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 주석에 따라 필요한 기능을 구현하세요. 주석은 추상 메서드 생성, 구체 서브클래스 구현, 파일 간의 적절한 import 관계 설정 과정을 단계별로 안내합니다.
driver.py 파일에는 구현이 올바르게 작동하는지 확인하는 테스트 케이스가 포함되어 있으며, 다양한 결제 시나리오를 처리하고 각 결제 수단에 대한 적절한 세부 정보를 표시합니다.
치트 시트
추상 클래스는 직접 인스턴스화할 수 없으며, 서브클래스에서 반드시 구현해야 하는 추상 메서드를 포함합니다.
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 데코레이터는 서브클래스에서 반드시 구현해야 하는 메서드를 표시합니다. 일반 메서드는 구현부를 가질 수 있습니다.
추상 클래스는 인스턴스화할 수 없습니다:
# 이 코드는 오류를 발생시킵니다:
# shape = Shape() # TypeError: Can't instantiate abstract class모든 추상 메서드를 구현하는 구체적인 서브클래스를 생성합니다:
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
circle = Circle(5)
print(circle.area()) # 78.5
print(circle.describe()) # 상속된 구체적인 메서드핵심 포인트: 추상 클래스는 서브클래스가 따라야 할 템플릿을 정의합니다. 서브클래스는 모든 추상 메서드를 구현해야 하며, 그렇지 않으면 해당 서브클래스도 추상 클래스가 됩니다.
직접 해보기
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() # 추상 클래스는 인스턴스화할 수 없습니다이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.