파이썬에서 추상 클래스는 주로 abc
모듈을 사용하여 정의한다. 추상 클래스는 하나 이상의 추상 메서드를 포함하는 클래스로, 직접 인스턴스화할 수 없다. 대신, 서브클래스에서 추상 메서드를 반드시 구현해야 한다. 이는 공통 인터페이스를 강제하고, 코드의 구조와 일관성을 유지하는 데 유용하다.
기본 사용법
추상 클래스를 정의하기 위해서는 abc.ABC
를 상속하고, abc.abstractmethod
데코레이터를 사용하여 추상 메서드를 정의한다.
from abc import ABC, abstractmethod
class Animal(ABC):
@abstractmethod
def sound(self):
pass
@abstractmethod
def move(self):
pass
# 사용 예시
class Dog(Animal):
def sound(self):
return "Bark"
def move(self):
return "Runs"
class Bird(Animal):
def sound(self):
return "Chirp"
def move(self):
return "Flies"
# 인스턴스 생성
dog = Dog()
bird = Bird()
print(dog.sound()) # Bark
print(dog.move()) # Runs
print(bird.sound()) # Chirp
print(bird.move()) # Flies
# 추상 클래스는 직접 인스턴스화할 수 없다.
try:
animal = Animal()
except TypeError as e:
print(e) # "Can't instantiate abstract class Animal with abstract methods move, sound"
자세한 설명
ABC 클래스
abc.ABC
는 파이썬에서 추상 클래스를 정의할 때 사용하는 기본 클래스이다. 이를 상속받는 클래스는 추상 클래스가 된다.
from abc import ABC
class MyAbstractClass(ABC):
pass
abstractmethod 데코레이터
abc.abstractmethod
데코레이터는 메서드를 추상 메서드로 정의하는 데 사용된다. 추상 메서드는 서브클래스에서 반드시 구현해야 하며, 구현하지 않을 경우 서브클래스도 추상 클래스가 된다.
from abc import ABC, abstractmethod
class MyAbstractClass(ABC):
@abstractmethod
def my_method(self):
pass
추상 클래스와 상속
추상 클래스는 서브클래스에서 구현해야 할 공통 인터페이스를 정의하는 데 유용하다. 서브클래스가 추상 메서드를 모두 구현하면, 인스턴스를 생성할 수 있다.
class ConcreteClass(MyAbstractClass):
def my_method(self):
print("This is the implementation of the abstract method")
# 사용 예시
obj = ConcreteClass()
obj.my_method() # This is the implementation of the abstract method
응용 예제
다음은 도형의 면적을 계산하는 추상 클래스를 정의하고, 이를 상속받는 서브클래스에서 면적을 계산하는 예제이다.
from abc import ABC, abstractmethod
class Shape(ABC):
@abstractmethod
def area(self):
pass
@abstractmethod
def perimeter(self):
pass
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)
class Circle(Shape):
def __init__(self, radius):
self.radius = radius
def area(self):
return 3.14159 * (self.radius ** 2)
def perimeter(self):
return 2 * 3.14159 * self.radius
# 사용 예시
rectangle = Rectangle(5, 10)
circle = Circle(7)
print("Rectangle area:", rectangle.area()) # Rectangle area: 50
print("Rectangle perimeter:", rectangle.perimeter()) # Rectangle perimeter: 30
print("Circle area:", circle.area()) # Circle area: 153.93804
print("Circle perimeter:", circle.perimeter()) # Circle perimeter: 43.98226