[디딤돌 C++] 32. 형식의 다형성

이번에는 형식의 다형성을 살펴볼게요. 형식의 다형성은 기반 형식 포인터 변수로 파생 형식 개체를 설정하거나 기반 형식 참조 변수로 파생 형식 개체를 설정할 수 있는 특징입니다.

일반화 관계 클래스 다이어그램

예를 들어 음악가 형식을 기반으로 파생한 형식으로 피아니스트와 드러머가 있다고 가정할게요. “피아니스트는 음악가이다.”, “드러머는 음악가이다.” 처럼 일반화관계로 정의하기 적합한 관계죠.

만약 음악가 형식 포인터 변수가 있다면 음악가 개체를 설정할 수 있겠죠. 그런데 피아니스트와 드러머는 음악가가 아닌가요? 네. 피아니스트나 드러머도 음악가입니다. 이러한 일반화관계의 특징을 OOP언어에서 활용할 수 있게 만든 문법이 다형성입니다.

void StartConcert(Musician *musician);
int main()
{
    Pianist *pianist1 = new Pianist("피아노맨1");
    Drummer *drummer1 = new Drummer("두둥맨1");
    StartConcert(pianist1);
    StartConcert(drummer1);
    delete pianist1;
    delete drummer1;
    return 0;
}
void StartConcert(Musician *musician)
{
    musician->Play();
}

위의 예처럼 음악가 형식 포인터 변수에 파생 형식의 개체를 전달받아 사용할 수 있습니다. 마찬가지로 음악가 형식 참조 변수로 파생 형식인 피아니스트와 드러머 개체를 전달받아 사용할 수 있어요.

void StartConcert(Musician &musician);

int main()
{
    Pianist pianist2("피아노맨2");
    Drummer drummer2("두둥맨2");
    StartConcert(pianist2);
    StartConcert(drummer2);
    return 0;
}

void StartConcert(Musician &musician)
{
    musician.Play();
}

void StartConcert(Musician &musician)
{
    musician.Play();
}

다음은 앞에서 예로 보여준 형식의 다형성을 확인하는 예제 코드입니다.

//형식의 다형성
//Program.cpp
#include <iostream>
#include <string>
using namespace std;
class Musician
{
    string name;
public:
    Musician(string name)
    {
        this->name = name;
    }
    void Play()
    {
        cout<<name<<" 연주하다."<<endl;
    }
};

class Pianist:public Musician
{
public:
    Pianist(string name):Musician(name)
    {
    }
};
class Drummer:public Musician
{
public:
    Drummer(string name):Musician(name)
    {
    }
};

void StartConcert(Musician *musician);
void StartConcert(Musician &musician);

int main()
{
    Pianist *pianist1 = new Pianist("피아노맨1");
    Drummer *drummer1 = new Drummer("두둥맨1");
    StartConcert(pianist1);
    StartConcert(drummer1);
    delete pianist1;
    delete drummer1;

    Pianist pianist2("피아노맨2");
    Drummer drummer2("두둥맨2");
    StartConcert(pianist2);
    StartConcert(drummer2);
    return 0;
}
void StartConcert(Musician *musician)
{
    musician->Play();
}
void StartConcert(Musician &musician)
{
    musician.Play();
}

▷ 실행 결과

피아노맨1 연주하다.

두둥맨1 연주하다.

피아노맨2 연주하다.

두둥맨2 연주하다.

이와 같은 다형성 특징을 이용하면 하나의 기반 형식에서 파생한 다양한 형식의 개체를 기반 형식 포인터 변수나 기반 형식 참조 변수를 사용할 수 있어 집합체를 다룰 때 효과적으로 프로그래밍 할 수 있습니다. 그런데 파생 형식의 종류에 관계없이 다 똑같이 동작하는 것은 개발자가 원하는 형태가 아닐 수 있습니다. 이러한 문제를 해결하기 위해 OOP 언어에서는 형식의 다형성과 함께 메서드의 다형성을 제공하고 있습니다.

형식의 다형성에 이어 다음 주제는 메서드의 다형성입니다.