7.1 super()
메서드
상속 계층을 얘기하는 김에, 기본 클래스의 필드와 메서드를 다루는 것에 대한 세부 사항들을 논의하는 것이 유용할 거야. Python에는 이걸 위해 특별한 메서드 super()
가 있어. 이 메서드는 자식 클래스 내에서 기본 클래스의 메서드를 호출할 때 사용돼.
이 메서드는 세 가지 주요 사용 사례가 있어:
부모 클래스 메서드 호출:
super()
메서드는 부모 클래스의 메서드를 자식 클래스에서 호출할 수 있게 해 줘, 부모 클래스의 이름을 명시적으로 지정할 필요가 없어. 특히 다중 상속을 다룰 때 유용하고, 클래스 계층을 변경할 때 발생할 수 있는 오류를 피하는 데 도움이 돼.
기본 클래스 초기화:
super()
는 자식 클래스의 생성자에서 기본 클래스의 생성자를 호출할 때 자주 사용돼, 이는 자식 클래스 내에서 기본 클래스의 속성을 초기화할 수 있게 해 줘.
다중 상속 지원:
다중 상속의 경우 super()
는 메서드 호출의 순서(MRO, Method Resolution Order)를 올바르게 해결해, 부모 클래스의 메서드를 명시적으로 호출하는 것보다 이를 사용하는 것이 더 선호돼. 이것에 대해서는 나중에 더 얘기할 거야.
7.2 기본 클래스의 생성자
기본 클래스의 생성자는 명시적으로 호출해야 해. 자동으로 발생할 것 같지만, 실제로는 그렇지 않아. 기본 클래스의 생성자는 항상 명시적으로 불러오고, 종종 특별한 인수를 전달해야 할 필요가 있기 때문이야.
예시:
class Animal:
def __init__(self, type, name):
self.type = type
self.name = name
class Dog(Animal):
def __init__(self, name):
super().__init__("개", name) # 기본 클래스 생성자 호출
class Cat(Animal):
def __init__(self, name):
super().__init__("고양이", name) # 기본 클래스 생성자 호출
# Dog 객체 생성
dog = Dog("Buddy")
print(dog)
이 예시에서 기본 클래스 (Animal)
의 생성자는 두 개의 매개변수를 가져: 동물의 타입과 그 이름. 그리고 상속 클래스는 하나만 가져 — 이름.
바로 Dog
와 Cat
클래스의 생성자에서 기본 클래스 생성자에 전달할 것이 결정돼 — 동물의 타입 이름인 "개"와 "고양이".
그래서:
- 기본 클래스의 생성자는 상속 클래스의 생성자에서 반드시 호출해야 해.
- 이를 위해
super()
메서드를 사용해야 해. -
self
매개변수를 따로 전달할 필요는 없어 — Python이 메서드를 호출할 때 자동으로 대입해 줄 거야.
7.3 super()
메서드 사용
super()
메서드는 Python에서 생성자뿐만 아니라 부모 클래스의 메서드를 호출하기 위해 클래스의 다른 메서드에서도 사용할 수 있어. 부모 클래스에 정의된 메서드의 동작을 확장하거나 수정해야 할 때 이게 유용할 수 있어.
몇 가지 예시를 살펴보자:
자식 메서드에서 부모 클래스의 메서드 호출
이 예시에서 Dog
클래스의 speak()
메서드는 먼저 super()
를 통해 Animal
클래스의 speak()
메서드를 호출한 다음에 자체 행동을 추가해.
class Animal:
def speak(self):
return "어떤 일반적인 동물의 소리"
class Dog(Animal):
def speak(self):
parent_speech = super().speak() # 부모 클래스의 메서드 호출
return f"{parent_speech} 그리고 개가 짖어!"
dog = Dog()
print(dog.speak()) # 출력: 어떤 일반적인 동물의 소리 그리고 개가 짖어!
부모 클래스의 메서드를 호출하여 상태 확인
이 예시에서 Dog
클래스의 check_health()
메서드를 통해 Animal
클래스의 check_health()
메서드를 호출하여 추가적인 검사를 수행해.
class Animal:
def check_health(self):
return "동물이 건강해"
class Dog(Animal):
def check_health(self):
parent_check = super().check_health() # 부모 클래스의 메서드 호출
return f"{parent_check}. 개가 산책이 필요해!"
dog = Dog()
print(dog.check_health()) # 출력: 동물이 건강해. 개가 산책이 필요해!
상태를 변경하는 메서드에서 부모 클래스의 메서드 호출
이 예시에서 SavingsAccount
클래스의 withdraw()
메서드는 먼저 인출 한도가 초과되지 않았는지 확인한 다음, 초과되지 않았다면 BankAccount
클래스의 withdraw()
메서드를 호출하여 작업을 수행해.
class BankAccount:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount
return f"{amount} 인출했어. 새로운 잔액: {self.balance}"
return "잔액 부족"
class SavingsAccount(BankAccount):
def withdraw(self, amount):
if amount > 1000:
return "인출 한도 초과"
return super().withdraw(amount) # 부모 클래스의 메서드 호출
savings = SavingsAccount(1500)
print(savings.withdraw(500)) # 출력: 500 인출했어. 새로운 잔액: 1000
print(savings.withdraw(1500)) # 출력: 인출 한도 초과