Class(4) - 상속
상속
클래스들의 공통된 속성과 메서드를 뽑아내서 부모 클래스를 만들고 이를 자식 클래스에서 상속 받아서 사용한다. 이렇게 하면 코드의 중복을 제거할 수 있고 유지보수가 편리해진다는 장점이 있다.
class Item:
def __init__(self, name):
self.name = name
def pick(self):
print(f'{self.name} 를 주웠습니다.')
def discard(self):
print(f'{self.name} 를 버렸습니다.')
class Weapon(Item):
def __init__(self, name, damage):
super().__init__(name)
self.damage = damage
def attack(self):
print(f'{self.name} 를 이용해 {self.damage}로 공격합니다.')
class HealingItem(Item):
def __init__(self, name, recovery_amount):
super().__init__(name)
self.recovery_amount = recovery_amount
def use(self):
print(f'{self.name} 를 이용해 {self.recovery_amount}를 회복합니다.')
w1 = Weapon('총', 110)
h1 = HealingItem('상처약', 20)
>>> w1.attack()
총 를 이용해 110로 공격합니다.
>>> h1.use()
상처약 를 이용해 20를 회복합니다.
추상 클래스
추상 클래스는 추상 메서드를 가질 수 있는데, 추상 메서드는 상속받는 자식 클래스에서 구현을 강제하도록 만드는 메서드이다. 추상 메서드를 하나라도 가지고 있는 클래스를 추상 클래스라고 한다.
추상클래스를 구현하기 위해서는 abc라는 모듈이 필요하고, 부모클래스에서 metaclass=ABCMeta라는 클래스를 상속받아야 한다. 추상 메서드는 @abstractmethod 데코레이터를 사용해야 한다.
from abc import *
class Item(metaclass=ABCMeta):
def __init__(self, name):
self.name = name
def pick(self):
print(f'{self.name} 를 주웠습니다.')
def discard(self):
print(f'{self.name} 를 버렸습니다.')
@abstractmethod
def use(self):
pass
class Weapon(Item):
def __init__(self, name, damage):
super().__init__(name)
self.damage = damage
def attack(self):
print(f'{self.name} 를 이용해 {self.damage}로 공격합니다.')
class HealingItem(Item):
def __init__(self, name, recovery_amount):
super().__init__(name)
self.recovery_amount = recovery_amount
def use(self):
print(f'{self.name} 를 이용해 {self.recovery_amount}를 회복합니다.')
만약에 자식 클래스에서 use()라는 메서드를 구현하지 않았으면 아래와 같은 에러가 발생한다.
>>> w1 = Weapon('총', 110)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: Can't instantiate abstract class Weapon with abstract methods use
반면에 use()함수를 자식 클래스에서 구현하면 문제없이 잘 돌아가는 것을 확인할 수 있다.
>>> h1 = HealingItem('상처약', 20)
>>> print(h1. recovery_amount)
20