from abc import ABC, abstractmethod
class FlyerInterface(ABC):
@abstractmethod
def fly(self) -> None:
pass
@abstractmethod
def nothing(self) -> None:
pass
class Bird(FlyerInterface):
def fly(self) -> None:
print("이 새는 날아다닙니다.")
bird = Bird()
def lift_off(entity: Flyer) -> None:
entity.fly()
lift_off(bird)
ABC(Abstract Base Classes)를 사용해서 인터페이스를 정의했다. 구현체에서 nothing()을 구현하고 있지 않아 에러가 발생한다.
ERROR!
Traceback (most recent call last):
File "<main.py>", line 36, in <module>
TypeError: Can't instantiate abstract class Bird with abstract method nothing
from abc import ABC, abstractmethod
class FlyerInterface(ABC):
@abstractmethod
def fly(self) -> None:
pass
class Bird(FlyerInterface):
def fly(self) -> None:
print("이 새는 날아다닙니다.")
def walk(self) -> None:
print("이 새는 걸어다닙니다.")
bird = Bird()
def lift_off(entity: FlyerInterface) -> None:
entity.fly()
def walk(entity: FlyerInterface) -> None:
entity.walk()
print(f"isinstance : {isinstance(bird, FlyerInterface)}")
print(f"issubclass : {issubclass(Bird, FlyerInterface)}")
lift_off(bird)
walk(bird)
Bird 구현체가 interface의 메서드를 모두 구현했으므로 FlyerInterface의 instance이면서 subclass다.
isinstance : True
issubclass : True
이 새는 날아다닙니다.
from typing import Protocol, runtime_checkable
@runtime_checkable
class Flyer(Protocol):
def fly(self) -> None:
print('flyer')
def nothing(self) -> None:
pass
class Bird:
def fly(self) -> None:
print("이 새는 날아다닙니다.")
bird = Bird()
def lift_off(entity: Flyer) -> None:
entity.fly()
print(f"isinstance : {isinstance(bird, Flyer)}")
print(f"issubclass : {issubclass(Bird, Flyer)}")
lift_off(bird)
Bird 클래스에 nothing()은 구현되어 있지 않고 fly만 구현되어 있어도 실행이 된다.
isinstance : False
issubclass : False
이 새는 날아다닙니다.
from typing import Protocol, runtime_checkable
@runtime_checkable
class Flyer(Protocol):
def fly(self) -> None:
print('flyer')
def nothing(self) -> None:
pass
class Whale:
def swim(self) -> None:
print("이 고래는 수영합니다.")
whale = Whale()
def lift_off(entity: Flyer) -> None:
entity.fly()
print(f"isinstance : {isinstance(whale, Flyer)}")
print(f"issubclass : {issubclass(Whale, Flyer)}")
lift_off(whale)
Whale 클래스에는 fly 메서드가 구현되어 있지 않다.
whale은 Flyer의 instance도 subclass도 아니다.
fly가 없다는 에러가 발생함.
isinstance : False
issubclass : False
ERROR!
Traceback (most recent call last):
File "<main.py>", line 23, in <module>
File "<main.py>", line 18, in lift_off
AttributeError: 'Whale' object has no attribute 'fly'
from typing import Protocol, runtime_checkable
@runtime_checkable
class Flyer(Protocol):
def fly(self) -> None:
print('flyer')
class Bird:
def fly(self) -> None:
print("이 새는 날아다닙니다.")
def walk(self) -> None:
print("이 새는 걸어다닙니다.")
bird = Bird()
def lift_off(entity: Flyer) -> None:
entity.fly()
def walk(entity: Flyer) -> None:
entity.walk()
print(f"isinstance : {isinstance(bird, Flyer)}")
print(f"issubclass : {issubclass(Bird, Flyer)}")
lift_off(bird)
walk(bird)
isinstance : True
issubclass : True
이 새는 날아다닙니다.
이 새는 걸어다닙니다.
ABC를 사용한 인터페이스는 구현체가 인터페이스의 모든 속성과 메서드를 구현하도록 강제한다.
Protocol을 사용한 인터페이스는 구현체가 인터페이스의 일부 속성과 메서드만 구현해도 되게 한다.