35. Python에서의 다형성 – 재정의(override)와 무효화

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

이전 강의에서 상속이 무엇인지 간략히 살펴보았어요. 이번 강의에서는 다형성 개념과 재정의(override)와 무효화에 관해 다룰 거예요. 먼저 재정의와 무효화가 무엇인지 살펴본 후에 다형성을 설명할게요.

재정의(override)는 기반 형식에 정의한 멤버 메서드와 같은 이름으로 파생 형식에서 정의하는 것을 말합니다. 이 때 해당 이름으로 접근하면 새롭게 정의한 파생 형식의 멤버를 접근합니다. 그리고 이럴 때 기반 형식의 해당 멤버를 무효화하였다고 말하죠.

다음은 음악가를 정의하고 이를 기반으로 파생 형식 피아니스트와 드러머를 구현한 예제입니다. 음악가에서 Play 메서드를 정의하였고 피아니스트에서 같은 이름으로 재정의하였습니다. 이 외에  피아니스트 형식에는 Tuning 메서드를 정의하였고 드러머 형식에는 TurnStick 메서드를 정의하였습니다.

이와 같이 정의하였을 때 피아니스트 개체를 참조하는 변수로 Play 메서드를 호출하면 기반 형식 Musician에 정의한 Play가 아닌 파생 형식 Pinanist에 정의한 Play를 수행합니다. 너무나 당연한 결과라고 생각할 수 있겠죠.

#무효화

class Musician:
    def Play(self):
        print("랄라라~")

class Pianist(Musician):
    def Play(self):
        print("딩동댕")

    def Tuning(self):
        print("도도 레레 미미")

class Drummer(Musician):
    def TurnStick(self):
        print("휘리릭~ 휘릭~")

print("===음악가===")
mu = Musician()
mu.Play()

print("===드러머===")
drummer = Drummer()
drummer.TurnStick()
drummer.Play()

print("===피아니스트===")
pianoman = Pianist()
pianoman.Tuning()
pianoman.Play()
[그림 1] 무효화 예제 실행 화면
[그림 1] 무효화 예제 실행 화면

결국 재정의를 하였을 때 기반 형식의 해당 멤버 메서드는 무효화 상태라는 것입니다.

이러한 특징은 OOP의 다형성의 주요 특징입니다. 다형성은 보이는 이름은 같지만 실제 모습 혹은 행위는 다른 특징을 말합니다.

다형성은 크게 형식의 다형성과 메서드의 다형성으로 나눌 수 있어요. 형식의 다형성은 특정 변수에 참조하는 개체의 형식은 다를 수 있음을 의미합니다. 그리고 메서드의 다형성은 특정 변수로 호출하는 메서드는 실제 참조하는 개체 형식에 따라 서로 다르게 정의한 메서드를 호출할 수 있음을 의미합니다.

다음 코드는 band 리스트에 피아니스트와 드러머 개체를 보관한 후에 연주를 하는 예제입니다. for 문에서 표현한 musician 변수는 피아니스트 개체를 참조할 수도 있고 드러머 개체를 참조할 수도 있습니다. 이는 형식의 다형성이라고 볼 수 있어요. (참고로 Python에서는 이 둘이 일반화 관계(OOP에서 상속)가 아니어도 이러한 표현이 가능합니다.)

또한 musician.Play() 부분은 musician 변수가 참조하고 있는 개체 형식에 따라 호출하는 메서드가 다르겠죠. 이 부분이 메서드의 다형성입니다.

#다형성 예제

class Musician:
    def Intro(self):
        print("방가우이 아라리요 ♩♬♪~")

    def Play(self):
        print("랄라라~")

class Pianist(Musician):
    def Play(self):
        print("딩동댕")

    def Tuning(self):
        print("도도 레레 미미")

class Drummer(Musician):
    def TurnStick(self):
        print("휘리릭~ 휘릭~")

band = list()
band.append(Pianist())
band.append(Drummer())

print("===단원 소개===")
for musician in band:
    musician.Intro()

print("===연주 시작===")
for musician in band:
    musician.Play()
[그림 2] 다형성 예제 실행 화면
[그림 2] 다형성 예제 실행 화면