34. Python에서의 상속 개요

안녕하세요. 언제나 휴일, 언휴예요.

이전 강의까지 Python에서의 캡슐화를 다루었어요. 이번에는 Python에서의 상속을 다룰게요.

OOP 언어에서 상속은 이미 정의한 형식을 기반으로 파생한 형식을 정의하였을 때 기반 형식에 정의한 멤버가 파생 형식에 정의한 것과 같은 효과를 갖는 특징을 말합니다. 그리고 상속을 UML로 표현할 때는 일반화(Generalization) 관계로 표현합니다.

피아니스트, 드러머, 기타 리스트로 구성한 밴드를 표현한다고 가정할게요. 피아니스트, 드러머, 기타 리스트에는 <음악가 번호>, <이름>, <연주하다>, <소개하다> 등의 멤버가 있고 피아니스트에는 <튜닝하다>, 드러머는 <스틱 돌리기>, 기타 리스트는 <헤드 뱅잉> 멤버가 있다고 가정합시다. 이 때 피아니스트와 드러머, 기타 리스트의 공통적인 특징을 음악가로 정의를 하고 이를 기반으로 파생 형식으로 피아니스트, 드러머, 기타 리스트를 정의하면 구현 효율이 높아집니다.

Python에서 상속을 표현할 때는 파생 형식을 정의할 때 클래스 이름 뒤에 괄호를 열고 기반 형식 이름을 명시합니다.

class 파생형식명(기반형식명):

    [정의]

다음은 음악가 클래스와 이를 기반으로 파생 형식 피아니스트 클래스를 정의한 예제입니다. 음악가 클래스에는 생성자와 <연주하다> 메서드를 정의하였고 피아니스트 클래스에는 생성자와 <튜닝하다> 메서드를 정의하였습니다. 그리고 사용하는 곳에서 피아니스트 개체를 생성하여 <연주하다>와 <튜닝하다> 메서드를 호출합니다.

피아니스트 클래스에는 <연주하다> 메서드를 정의하지 않았지만 피아니스트 형식은 음악가 형식을 기반으로 파생한 형식이어서 기반 형식에 정의한 <연주하다> 메서드를 호출하는 것이 가능합니다. 이는 피아니스트 개체는 기반 형식인 음악가 형식의 멤버를 상속받고 있기 때문입니다. 따라서 <파생 형식 개체는 기반 형식 개체이다.> 논리가 성립하며 <피아니스트는 음악가이다>처럼 해당 논리가 성립할 때 상속 문법을 활용하여 표현하였을 때 구현 효율을 높일 수 있어요.

#상속 개요

class Musician:
    def __init__(self):
        print("음악가 __init__")
    def Play(self):
        print("음악가 연주하다.")

class Pianist(Musician):
    def __init__(self):
        print("피아니스트 __init__")
    def Tuning(self):
        print("피아니스트 튜닝하다.")

mu = Pianist()
mu.Tuning()
mu.Play()
[그림 1] 상속 개요 실행 화면(음악가, 피아니스트)
[그림 1] 상속 개요 실행 화면(음악가, 피아니스트)

다음은 UML에서 일반화 관계를 표시한 것입니다. 참고로 Star UML을 이용했어요.

일반화 관계 클래스 다이어그램
[그림 2] 일반화 관계