작성
·
18
1
안녕하세요 상속에 대해 질문 드립니다.
만약에
class GrandParents:
def __init__(self):
self.grandmother = 80
self.grandfather = 70
class Parents(GrandParents):
def __init__(self):
super().__init__()
self.mother = 50
self.father = 50
class Child(Parents):
def __init__(self):
super().__init__()
child_obj = Child()
print(child_obj.grandmother)
print(child_obj.grandfather)
위와 같이 상속을 진행한다고 했을 때,
Child 클래스로 객체를 만들어 초기화를 진행하면 GrandParents의 생성자가 딸려나오는걸 볼수가 있는데
super().__init__을 사용할 때,
내(Child)가 상속받은 클래스(Parents) 내부의 메서드에서 상위 클래스(GrandParents)를 super()로 가져온다면
Child 클래스는 언제나 Parents와 GrandParents의 속성을 다 가지게 되는 것인가요??
이런 식으로 상속하는 방식을 실무에서 자주 쓰기도 하는지 궁금합니다.
그리고 만약에, 저 상황에서 Child 클래스가 super().__init__을 사용하면서 GrandParents의 것을 가져오지 않고 Parents의 생성자만 super()로 가지고 올 수도 있나요??
강의 잘 듣고 있습니다. 감사합니다.
답변 2
0
안녕하세요 천천히꾸준하게님,
아이디가 아주 마음에 드네요 ㅎㅎㅎ
Q1. Child 객체를 만들면 GrandParents 생성자도 실행되는데, 이게 항상 그런가요?
네, 맞습니다.
class Parents(GrandParents):
def __init__(self):
super().__init__() # GrandParents의 생성자 호출
Child
클래스의 생성자에서 super().__init__()
을 호출하면, 그건 Parents
의 생성자를 호출하게 됩니다. 그런데 Parents
생성자 안에 또 super().__init__()
이 있기 때문에, 결과적으로 GrandParents까지 호출되는 거죠.
즉, 연쇄적으로 올라가서 모든 조상 클래스의 생성자가 호출됩니다. 그래서 Child
객체는 grandmother
, grandfather
, mother
, father
속성을 다 가지게 되는 거예요.
Q2. 이런 식의 상속 방식, 실무에서 자주 쓰이나요?
꼭 필요한 경우에만 이런 다단계 상속을 씁니다.
실무에서는 일반적으로 다음과 같은 방식이 더 선호됩니다:
상속은 깊지 않게 (2단계 정도가 적절)
공통된 기능은 Mixin이나 Composition(구성) 방식으로 해결
super()
는 명확한 초기화 순서를 관리할 때 사용
파이썬의 다이아몬드 상속(Multiple Inheritance)이 복잡한 문제를 일으킬 수 있기 때문에, 다단계 상속은 구조가 단순하거나, 잘 설계된 프레임워크 안에서만 사용하는 편이 좋습니다.
Q3. Child 클래스에서 super()를 호출할 때, GrandParents는 빼고 Parents만 호출할 수 있나요?
사실상 직접적으로 Parents만 호출한다는 건 불가능합니다.
왜냐면 super()는 메서드 탐색 순서(Method Resolution Order, MRO)에 따라 위로 올라가며 init()을 호출하는 방식이기 때문입니다. 만약 정말 Parents
까지만 호출하고 싶고, GrandParents
는 제외하고 싶다면 Parents 클래스에서 super()를 아예 호출하지 않도록 수정해야 합니다.
그럼 도움이 되셨길 바라겠습니다 ~~!
0
안녕하세요, 인프런 AI 인턴입니다. 천천히꾸준하게님께서 올리신 상속에 관한 질문에 답변 드리겠습니다.
파이썬에서 상속은 클래스 간에 속성과 메서드를 공유하는 기능을 제공합니다. 질문하신 코드 구조로 보면 Child
클래스는 부모 클래스인 Parents
의 __init__
메서드를 통해 GrandParents
의 속성까지 상속받게 됩니다. 이를 통해 Child
객체는 grandmother
, grandfather
, mother
, father
의 속성을 모두 가지게 됩니다.
Child
는 Parents
를 상속받고, Parents
는 GrandParents
를 상속받습니다.super().__init__()
를 사용하면 바로 위의 부모 클래스의 __init__
메서드를 호출합니다. 이 호출은 체인을 따라 위로 올라가며, GrandParents
의 __init__
까지 호출하게 됩니다.Child
클래스는 결과적으로 모든 조상의 속성을 상속받게 되는 것입니다.이런 형태의 다중 상속 체인은 실무에서도 사용될 수 있지만, 설계의 복잡성을 고려해야 합니다. 상속 구조가 깊어질수록 관리가 어려워질 수 있고, 상위 클래스의 변경이 하위 클래스에 예기치 않은 영향을 줄 수 있으므로 주의가 필요합니다. 따라서 상속보다는 구성(Composition)을 통해 객체를 조립하는 방식이 권장되는 경우도 많습니다.
질문에서 언급하신 대로, Child
클래스에서 GrandParents
의 것을 가져오지 않고 Parents
의 속성만 가지고 오고자 한다면 구조를 재설계해야 합니다. 현재 구조에서는 Parents
가 GrandParents
의 __init__
을 호출하기 때문에 Child
는 그 속성까지 모두 상속받게 됩니다. 이를 피하려면 Parents
클래스에서 super().__init__()
호출을 제거하거나, Child
에서 직접 속성을 초기화하는 방안을 고려할 수 있습니다.
관련 정보를 좀 더 알고 싶으시면, 다음 링크들을 참고해주세요:
- 자바와 파이썬은 상속문법이 서로 원래 달라서 그런건가요?
- import class에 대해 알아보기 수업에서 질문이 있습니다.
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다. 현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏 추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.