[Py: Class] 2.클래스 상속
부모 클래스와 자식 클래스
파이썬의 class는
상속(inheritance)
이라는 것을 할 수 있다.
A class가 Z class를 상속했다고 가정해보자.
이때, 두 클래스를 다음과 같이 칭한다.- A class :
부모 클래스
,슈퍼 클래스
,상위 클래스
- Z class :
자식 클래스
,서브 클래스
,하위 클래스
- A class :
그리고,
상속
에 의해서 다음과 같은 일을 할 수 있다.- 부모 class가 갖는 모든 메소드가 자식 class에도 담긴다.
- 자식 class는 부모 class의 메소드와 별도로 추가 메소드를 정의할 수 있다.
아래의 예제에서 자식 클래스가 부모 클래스의 메소드를 사용하고,
별도로 정의된 메소드까지 사용하는 것을 확인할 수 있다.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
class parent: def parent_ability(self): print("Do parent ability") class child(parent): # <- 상속하는 방법 확인 def child_ability(self): print("Do child ability") def main(): s = child() s.parent_ability() s.child_ability() main() # Do parent ability # Do child ability
더불어, 한 번에 둘 이상의 클래스를 상속하는 것도 가능하다. 하지만, 둘 이상의 클래스를 동시에 사용하면 구조가 복잡해지고 주의해야 할 사항들이 늘어나기 때문에 일반적으로는 둘 이상의 클래스를 동시에 상속하지 않는다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
class father: def father_ability(self): print('Do father ability!') class mother: def mother_ability(self): print('Do mother ability!') class child(father, mother): def child_ability(self): print('Do child ability!') def main(): s = child() s.father_ability() s.mother_ability() s.child_ability() main() # Do father ability! # Do mother ability! # Do child ability!
- 정리하면 다음과 같다.
- 자식 클래스는 부모 클래스의 메소드를 사용할 수 있다.
- 더불어, 자식 클래스에서 별도로 정의된 메소드도 사용할 수 있다.
- 자식 클래스는 둘 이상의 부모 클래스를 상속받을 수 있다.
메소드 오버라이딩과 super
부모 클래스가 갖는 메소드와 동일한 이름의 메소드를 자식 클래스에가 정의하는 경우도 있다.
이를 가리켜메소드 오버라이딩
이라고 한다.메소드 오버라이딩
이 수행될 경우, 부모 클래스의 메소드는 보이지 않는 상태(= 호출이 불가능한 상태, del된 것이 아님)가 된다.아래의 예제의 경우, sun class의 strong_ability메소드가 father class의 strong_ability메소드를 가린 상태이다.
즉, 삭제된 상태가 아니다. 두 메소드 모두 온전히 존재한다.1 2 3 4 5 6 7 8 9 10 11 12 13
class father: def strong_ability(self): print('strong father') class sun(father): def strong_ability(self): print('more stronger than fater') def main(): s = sun() s.strong_ability() main() # more stronger than fater
사라진 것이 가려졌을 뿐이기에 가려진 메소드의 이름 앞에
super()
을 붙여서 사용할 수 있다.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
class father: def strong_ability(self): print('strong father') class sun(father): def strong_ability(self): print('more stronger than fater') def hide_strong_ability(self): super().strong_ability() def main(): s = sun() s.strong_ability() s.hide_strong_ability() main() # more stronger than fater # strong father
init 메소드의 오버라이딩
- 다음과 같은 상황이 존재할 수 있다.
__init__메소드 오버라이딩
을 해야만 하는 상황- 동시에 가려진 메소드(즉,
오버라이딩된 메소드
)를 호출해야하는 상황
아래의 예제에서는
__init__
메소드가오버라이딩
되었으며 차와 트럭의 무게의 정보를 정의하기 위해서 가려진 메소드를 호출해야만 하는 상황에 해당한다. 이때, truck class의__init__
메소드에서super()
를통해 car class의__init__
메소드를 호출한 것을 확인할 수 있다. 즉, truck의 class에 상속된 car의 변수들을 자동으로 생성시키고 선언할 수 있게된다.1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
class car: def __init__(self, id, f): self.id = id self.fuel = f def drive(self): self.fuel -= 10 def add_fuel(self, f): self.fuel += f def show_info(self): print(f"id : {self.id}") print(f"fuel : {self.fuel}") class truck(car): def __init__(self, id, f, c): super().__init__(id, f) self.cargo = c def add_cargo(self, c): self.cargo += c def show_info(self): super().show_info() print(f"cargo : {self.cargo}") def main(): s = truck('42럭5959', 0, 0) s.add_fuel(100) s.add_cargo(50) s.drive() s.show_info() main() # id : 42럭5959 # fuel : 90 # cargo : 50
따라서, 위와 같은 상황에서는 자식 클래스의
__init__
은 부모의 변수를 초기화하기 위한 값도 함께 전달받아야 한다.
References
- 윤성우, 『윤성우의 열혈 파이썬 중급편』, ORANGE MEDIA(2021)