1. 상속
- 한 클래스의 속성과 메서드를 다른 클래스에 전달하는 기능
- 이는 기존 코드의 재사용과 확장에 도움을 줌
- 기본적으로 파이썬의 모든 클래스는 object라는 기본 클래스로부터 상속을 받음
class Parent:
pass
class Child(Parent):
pass
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print(f'{self.name} {food} 먹습니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 잠을 잡니다')
animal = Animal('동물', 10)
animal.eat('먹이')
animal.sleep(10)
class Cat(Animal):
pass
# Animal 클래스를 상속 받았기 때문에 Animal 클래스의 생성자 매개변수 전달
Manbo = Cat('만보', 13)
Manbo.eat('사료')
Manbo.sleep(12)
2. 클래스 상속 시 생성자 호출 순서
- 자식 클래스(child class)의 생성자 호출가 호출된다.
- 자식 클래스의 생성자에서 부모 클래스(parent class)의 생성자를 호출해야 하는데, 이를 위해 super() 함수를 사용한다. super() 함수는 현재 클래스의 부모 클래스를 참조하며 부모 클래스의 생성자를 호출할 수 있다.
- 부모 클래스의 생성자가 호출된다.
- 부모 클래스의 생성자가 실행을 마치면서 자식 클래스의 생성자로 돌아가 자식 클래스의 생성자 코드가 실행된다.
class Parent:
def __init__(self):
print('부모 클래스 생성자 호출') # 2
class Child(Parent):
def __init__(self):
print('Child 클래스 생성자 호출') # 출력 순서: 1
super().__init__()
print('모든 생성자 호출 완료') # 3
child = Child()
3. object 클래스
- 파이썬에서 모든 클래스의 부모 클래스 역할을 하는 기본 클래스
- 파이썬에서 정의하는 모든 클래스는 자동으로 object 클래스를 상속받아, 이 클래스에서 제공하는 기본적인 동작과 메서드를 사용할 수 있게 됨
- 예) __srt__(), __repr__(), __eq__(), __hash__() 등
class MyClass:
pass
# 위의 코드는 다음과 동일
class MyClass(object):
pass
4. 메서드 오버라이딩(Method Overriding)
- 서브 클래스(자식 클래스)에서 슈퍼 클래스(부모 클래스)의 메서드를 재정의하는 것
- 오버라이딩 사용 시 서브 클래스에서 상속받은 메서드의 동작을 변경 또는 확장 가능
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print(f'{self.name} {food} 먹습니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 잠을 잡니다')
class Cat(Animal):
def run(self):
print(f'{self.name} 달립니다')
Manbo = Cat('만보', 13)
Manbo.eat('사료')
Manbo.sleep('12')
Manbo.run()
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print(f'{self.name} {food} 먹습니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 잠을 잡니다')
class Cat(Animal):
def run(self):
print(f'{self.name} 달립니다')
# 시그니처: 메서드의 이름, 매개변수의 타입과 개수 모두 일치해야 함
def eat(self, food):
print(f'{self.name} {food}를 아주 맛있게 먹습니다')
def superEat(self, food):
super().eat(food)
Manbo = Cat('만보', 13)
Manbo.eat('사료')
Manbo.sleep('12')
Manbo.run()
Manbo.superEat('사료')
animal = Animal('동물', 10)
animal.eat('먹이')
animal.sleep(10)
# animal.run() # AttributeError: 'Animal' object has no attribute 'run'
# 부모는 자식 클래스에만 존재하는 것은 사용 불가능
5. 다중 상속
- 둘 이상의 부모 클래스로부터 상속을 받는 기능
- 다중 상속은 코드의 재사용성을 향상시키지만 동시에 복잡성이 높아지므로 사용 시 주의해야 함
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print(f'{self.name} {food} 먹습니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 잠을 잡니다')
class Human:
def __init__(self, name, age):
self.name = name
self.age = age
def study(self, hour):
print(f'{self.name} {hour}시간 동안 공부를 합니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 꿀잠 잡니다')
class Kim(Animal, Human):
pass
class Kim(Animal, Human):
pass
kim = Kim('김사과', 20)
kim.eat('밥')
kim.study(2)
kim.sleep(8) # Animal 클래스의 sleep이 동작
print(Kim.mro())
# [<class '__main__.Kim'>, <class '__main__.Animal'>, <class '__main__.Human'>, <class 'object'>]
# Animal 클래스가 우선 순위
C3 선형화 알고리즘
- 파이썬의 다중 상속에서 메서드 해결 순서(Method Resolution Order, MRO)를 계산하는 데 사용되는 알고리즘
- 복잡한 상속 구조에서 메서드 호출 순서를 명확하게 결정하기 위해 고안됨
- C3 선형화 규칙
- 자식 클래스가 항상 부모 클래스보다 먼저 온다.
- 부모 클래스들은 상속된 순서대로 나타난다.
- 충돌을 해결할 때는 왼쪽에 있는 부모 클래스의 순서를 우선시한다.
class Animal:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, food):
print(f'{self.name} {food} 먹습니다')
def sleep(self, hour):
print(f'{self.name} {hour}시간 동안 잠을 잡니다')
class Human:
def __init__(self, name, age, height):
self.name = name
self.age = age
self.height = height
def study(self, hour):
print(f'{self.name} {hour}시간 동안 공부를 합니다')
def sleep(self, hour):
print(f'키가 {self.height}인 {self.name} {hour}시간 동안 꿀잠 잡니다')
class Kim(Animal, Human):
def __init__(self, name, age, height):
Animal.__init__(self, name, age)
Human.__init__(self, name, age, height)
def sleep(self, hour):
Human.sleep(self, hour) # Human 부모 클래스 상속
kim = Kim('김사과', 20, 160)
kim.eat('밥')
kim.study(2)
kim.sleep(8) # 자식 클래스에 있는 sleep() 동작
6. super() 함수
- 파이썬의 내장 함수로서 상속과 관련된 작업 수행 시 사용됨
- 자식 클래스에서 부모 클래스의 메서드를 호출할 때 주로 사용
- 자식 클래스에서 부모 클래스의 메서드를 오버라이드(재정의)하면서도 오버라이드된 메서드 내에서 부모 클래스의 원본 메서드를 호출함
class Parent:
def hello(self):
print('부모 클래스의 hello 메서드')
class Child(Parent):
def hello(self):
super().hello()
print('자식 클래스의 hello 메서드')
child = Child()
child.hello()
class Parent:
def __init__(self, value):
self.value = value
class Child(Parent):
def __init__(self, value, child_value):
super().__init__(value)
self.child_value = child_value
child = Child(10, 20)
print(child.value) # 10
print(child.child_value) # 20
문제
아래 다중 상속 클래스의 출력을 예측해보자
class Base:
def hello(self):
print('Base의 hello()') # 7
print('Base 클래스의 hello() 메서드') # 8
class A(Base):
def hello(self):
print('A의 hello()') # 3
super().hello() # 4
print('A 클래스의 hello() 메서드') # 10
class B(Base):
def hello(self):
print('B의 hello()') # 5
super().hello() # 6
print('B 클래스의 hello() 메서드') # 9
class Child(A, B):
def hello(self):
print('Child의 hello()') # 1
super().hello() # 2
print('Child 클래스의 hello() 메서드') # 11
child = Child()
child.hello()
Child.mro() # [__main__.Child, __main__.A, __main__.B, __main__.Base, object] # -> 순서로 부모
'파이썬 > 파이썬 기초 문법' 카테고리의 다른 글
파이썬의 예외 처리 (0) | 2024.10.20 |
---|---|
파이썬 스페셜 메서드 (4) | 2024.10.19 |
클로저와 데코레이터 (1) | 2024.10.14 |
객체지향과 클래스 (0) | 2024.10.14 |
파이썬 콜백 함수와 람다 함수 (1) | 2024.10.07 |