개요
최근 Python으로 Class를 직접 정의하여 작업하는 경우가 잦은데, 슬슬 추상 클래스나 인터페이스에 대한 수요가 생기기 시작했다.
이번 글에서는 추상 클래스에 대한 개념을 되짚어보면서 Python으로 추상 클래스를 정의하는 방법을 적어둔다.
추상 클래스
추상 메서드(Abstract Method)란 구현 없이 선언만 되어 있는 메서드를 말한다. 그리고 추상 클래스는 하나 이상의 추상 메서드를 가진 클래스를 말한다. 추상 클래스를 상속한 자식 클래스가 추상 메서드를 반드시 구현하도록 강제하여 기능을 확장하고자 할 때 사용한다. 클래스이기 때문에 변수나 일반 메서드를 정의할 수 있지만, 직접 객체를 생성할 수 없다는 특징이 있다.
추상 클래스는 추상화라는 기법을 클래스에 접목시킨 것으로, 객체를 구조적으로 설계하고 프로그램의 유지보수성을 높이면서, 유연하게 프로그램을 수정할 수 있도록 한다. 개별 프로젝트보다는 범용 라이브러리나 프레임워크 설계에 많이 사용한다.
추상 클래스 정의
Python에서는 abc 모듈을 사용하여 추상 클래스를 정의할 수 있다.
from abc import *
그리고 추상 클래스를 정의할 때 괄호 안에 metaClass를 ABCMeta를 지정하여 생성하고, 추상 메서드에는 @abstractmethod라는 데코레이터를 붙인다.
from abc import *
class Character(metaclass=ABCMeta):
@abstractmethod
def print_status(self):
pass
위의 코드는 print_status라는 추상 메서드를 가진 Charater라는 추상 클래스를 정의한 것이다.
참고로 추상 메서드는 반드시 빈 메서드일 필요는 없다. 하지만 일반적으로는 추상 메서드는 자식 메서드에 반드시 구현해야하기 때문에 추상 클래스에서 선언한 추상 메서드는 호출될 일이 없다. 즉, 무의미하다.
다만 자식 클래스의 추상 메서드 구현에서 추상 메서드를 호출한다면 유의미한 코드를 집어넣어도 괜찮다.
추상 클래스 사용
정의한 추상 클래스는 자식 클래스에 상속하여 사용할 수 있다.
아래 코드는 위에서 정의한 추상 클래스인 Charater를 상속한 Warrior 클래스이다.
class Warrior(Character):
def __init__(self, name):
self.name = name
self.life = 1000
def print_status(self):
print(f"[{type(self).__name__}] name: {self.name}, life: {self.life}")
정의한 Warrior 클래스로 객체를 만들어, print_status 함수를 호출해보자.
james = Warrior('james')
james.print_status()
아래와 같이 잘 동작하는 모습을 확인할 수 있다.
+
만약 추상 클래스로 객체를 만들려고 하면, 다음과 같은 TypeError가 발생할 수 있다.
또한 자식 클래스에서 추상 클래스의 추상 메서드를 모두 구현하지 않으면 아래와 같은 에러가 발생하므로 주의해야 한다.
참고 문서
https://dojang.io/mod/page/view.php?id=2389