객체지향 프로그래밍에서 인터페이스가 무엇일까?
우선 인터페이스의 정의를 살펴보자.
인터페이스는 서로 다른 두 개의 시스템, 장치 사이에서 정보나 신호를 주고받는 경우의 접점이나 경계면이다. 즉, 사용자가 기기를 쉽게 동작시키는데 도움을 주는 시스템을 의미한다.
- 위키백과
인터페이스는 서로 다른 시스템이나 장치 사이의 정보나 신호를 주고받는 경계면을 의미한다고 한다.
이렇게만 보면 정확히 어떤 의미인지 이해하기 어렵다.
객체지향 프로그래밍에서 인터페이스는 클래스가 반드시 가져야하는 메소드를 정해준다.
인터페이스를 상속받은 클래스는 인터페이스에서 선언한 메소드를 반드시 재정의해서 사용해야 한다.
재정의하지 않고 해당 클래스로 객체를 생성하려고 하면 에러를 발생시킨다.
정의를 객체지향 언어에 대입시켜 생각해보면, 사용자는 인터페이스를 통해, 해당 인터페이스를 상속받은 클래스가 어떤 역할을 할지, 어떤 메소드를 사용할 수 있는지 쉽게 알 수 있다는 말로 해석할 수 있다.
인터페이스를 쉽게 이해하려면 하나의 자격증명서, 라이센스라고 보면 된다.
예를 들어보자.
운전면허증과 운전면허증을 소지하고 있는 사람을 생각해보자.
우리는 운전면허증을 가진 사람은 운전을 할 수 있다고 기대한다.
즉, 인터페이스 운전면허증을 상속받은 사람 class는 운전을 할 수 있어야 한다.
자바는 다중상속을 지원하지 않기 때문에 인터페이스를 활용해서 다중상속과 동일한 기능을 구현한다고 한다.
파이썬에서 인터페이스의 형태는 추상메소드만으로 구성된 추상클래스라고 보면 된다.
파이썬에서는 내장된 인터페이스 기능이 없기 때문에 abc 모듈을 임포트해서 기능을 구현할 수 있다.
abc는 abstract base class, 추상 기반 클래스를 의미한다.
아래에 운전면허증으로 예시를 들어보자.
import abc
# 인터페이스
class 운전면허1종보통(abc.ABC):
"""인터페이스 입니다. 반드시 추상메소드를 재정의 해주세요."""
@abc.abstractmethod
def 운전하기(self):
pass
# 추상클래스
class 사람:
""" 사람 추상 클래스 입니다."""
def __init__(self, 이름, 나이, 성별, 주소):
self.이름 = 이름
self.나이 = 나이
self.성별 = 성별
self.주소 = 주소
def 이름바꾸기(self, 새이름):
self.이름 = 새이름
def 주소바꾸기(self, 새주소):
self.주소 = 새주소
def 걷기(self):
pass
def 말하기(self):
pass
class 울산사람(운전면허1종보통, 사람):
def 걷기(self):
print(f"{self.이름} 님이 천천히 걸어갑니다.")
def 말하기(self):
print(f"{self.이름}: 울산사투리 첨 들어보나? 뭘 신기해하노")
# def 운전하기(self):
# print(f"{self.이름} 님이 1종보통 차량을 운전합니다.")
우선 운전하기 메소드를 오버라이드하지 않고 객체를 생성해 보자.
홍길동 = 울산사람("홍길동", 32, "남자", "울산")
-결과-
TypeError: Can't instantiate abstract class 울산사람 with abstract methods 운전하기
아래와 같이 "함수: 운전하기"를 abstract methods로 가진 "클래스: 울산사람"이라는 abstract class는 instance를 만들 수 없다는 타입 에러가 발생한다.
이제 운전하기 주석을 풀고 다시 돌려보자.
class 울산사람(운전면허1종보통, 사람):
def 걷기(self):
print(f"{self.이름} 님이 천천히 걸어갑니다.")
def 말하기(self):
print(f"{self.이름}: 울산사투리 첨 들어보나? 뭘 신기해하노")
def 운전하기(self):
print(f"{self.이름} 님이 1종보통 차량을 운전합니다.")
홍길동 = 울산사람("홍길동", 32, "남자", "울산")
홍길동.운전하기()
홍길동.말하기()
홍길동.걷기()
-결과-
홍길동 님이 1종보통 차량을 운전합니다.
홍길동: 울산사투리 첨 들어보나? 뭘 신기해하노
홍길동 님이 천천히 걸어갑니다.
정상적으로 잘 생성 되었음을 알 수 있다.
import abc
# 인터페이스
class 운전면허1종보통(abc.ABC):
"""인터페이스 입니다. 반드시 추상메소드를 재정의 해주세요."""
@abc.abstractmethod
def 운전하기(self):
pass
이처럼 인터페이스로 활용할 클래스는 abc.ABC 클래스를 상속받는다.
(※abc.ABC 클래스를 상속 받는 것과 metaclass=abc.ABCMeta 를 설정하는 방식이 있는데, 후자의 방식이 더 최근에 나온 방식이다. 아직 metaclass에 대한 이해가 부족해서 자세한 설명을 하지 못한다. 다음에 이해 한 후 이 포스트를 수정할 것이다.)
그리고 반드시 재정의 하기를 원하는 추상메소드에 @abc.abstractmethod 데코레이터를 사용한다.
그렇게 하면 해당 메소드를 오버라이드 하지 않고는 클래스를 생성할 수 없게 된다.
(abc.ABC 상속이나 @abc,abstractmethod 중 하나라도 하지 않으면 인터페이스로 동작하지 않는다.)
각각 이해를 하고 싶은데, 아직 관련 지식이 부족해서 사용하는 방법만 포스트 해놓겠다.
이해를 하고 나면 이 포스트를 수정할 것이다.
'파이썬' 카테고리의 다른 글
type - Class에 대한 이해 1(Python) (0) | 2023.11.25 |
---|---|
추상클래스 (Abstract class) in python (0) | 2021.11.13 |
데코레이터 (Decorator) in python (0) | 2021.11.02 |