언어 자료구조 알고리즘/디딤돌 C++

[C++] 34. 추상 클래스(ABSTRACT CLASS)

언제나휴일 2016. 4. 25. 00:31
반응형


추상 클래스(ABSTRACT CLASS)

이번에는 추상(Abstract) 클래스를 살펴볼게요.

 

추상 클래스는 다른 형식의 기반 클래스로만 사용할 수 있고 개체를 생성할 수 없는 클래스를 말합니다. 이에 대응하는 개념으로 개체를 생성할 수 있는 클래스를 구상 클래스입니다. .C++언어에서는 멤버 메서드 중에 순수 가상 메서드를 하나라도 갖고 있는 클래스는 추상 클래스입니다.

 

순수 가상 메서드는 virtual 키워드로 메서드를 선언하고 메서드 내부를 정의하지 않겠다는 =0;를 표시한 메서드를 말합니다. 그리고 순수 가상 메서드는 다른 OOP 언어에서 추상 메서드와 같은 의미입니다.

virtual void Play()=0; //순수 가상 메서드(추상 메서드)

다음은 순수 가상 메서드를 갖고 있는 음악가 클래스의 개체를 생성하려고 할 때 나오는 오류 화면입니다.

추상 클래스를 인스턴스화할 수 없습니다.


Program.cpp


//추상 클래스 개체를 생성하려고 할 때의 오류

//Program.cpp

#include <iostream>

#include <string>

using namespace std;

class Musician

{

    string name;

public:

    Musician(string name)

    {

        this->name = name;

    }

    virtual void Play()=0; //순수 가상 메서드(추상 메서드)

    void Introduce()

    {

        cout<<name<<" 음악가: 안녕"<<endl;

    }   

    string GetName()const

    {

        return name;

    }

};

 

int main()

{

    Musician *musician = new Musician("음악가"); //추상 클래스의 개체를 생성할 수 없음(오류)

    delete musician;

    return 0;

}

 

그리고 기반 형식에 순수 가상 메서드가 있을 때 파생 형식에서 이를 재정의하지 않으면 파생 형식도 추상 클래스입니다. 따라서 파생 형식을 구상 클래스로 만들기 위해서는 반드시 기반 형식에 순수 가상 메서드를 재정의하여야 합니다.

 

다음은 기반 형식이 추상 클래스일 때 파생 형식에서 재정의하지 않고 개체를 생성하려고 할 때 나오는 오류 화면입니다.

추상 클래스를 인스턴스화할 수 없습니다.


Program.cpp


//추상 클래스에서 파생한 클래스에서 순수 가상 메서드를 재정의하지 않고 개체를 생성할 때의 오류

//Program.cpp

#include <iostream>

#include <string>

using namespace std;

 

class Musician

{

    string name;

public:

    Musician(string name)

    {

        this->name = name;

    }

    virtual void Play()=0; //순수 가상 메서드(추상 메서드)

    void Introduce()

    {

        cout<<name<<" 음악가: 안녕"<<endl;

    }   

 

    string GetName()const

    {

        return name;

    }

};

class Pianist:public Musician

{

public:

    Pianist(string name):Musician(name)

    {

    }

};

 

int main()

{

    Pianist *pianist = new Pianist("피아노맨"); //추상 클래스의 개체를 생성할 수 없음(오류)

    delete pianist;

    return 0;

}

 

추상 클래스를 이용하면 파생 형식에 공통으로 제공해야 하는 기능이 있지만 실제 구현에서 공통적인 알고리즘이 없을 때 순수 가상 메서드로 기능을 약속할 수 있습니다.

 

다음은 음악가의 연주하다.”기능을 순수 가상 메서드로 선언하고 파생 클래스에서 재정의하는 예제 코드입니다.


Program.cpp


//추상 클래스

//Program.cpp

#include <iostream>

#include <string>

using namespace std;

class Musician

{

    string name;

public:

    Musician(string name)

    {

        this->name = name;

    }

    virtual void Play()=0; //순수 가상 메서드(추상 메서드)

    void Introduce()

    {

        cout<<name<<" 음악가: 안녕"<<endl;

    }   

 

    string GetName()const

    {

        return name;

    }

};

 

class Pianist:public Musician

{

public:

    Pianist(string name):Musician(name)

    {

    }

    virtual void Play()

    {

        cout<<GetName()<<" 연주하다."<<endl;

        cout<<"딩동댕 ♩♪♬"<<endl;

    }

};

class Drummer:public Musician

{

public:

    Drummer(string name):Musician(name)

    {

    }

    virtual void Play()

    {

        cout<<GetName()<<" 연주하다."<<endl;

        cout<<"두두둥~~~"<<endl;

    }

};

 

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->Introduce();

    musician->Play();

}

void StartConcert(Musician &musician)

{

    musician.Introduce();

    musician.Play();

}

 

▷ 실행 결과

피아노맨1 음악가: 안녕

피아노맨1 연주하다.

딩동댕 ♩♪♬

두둥맨1 음악가: 안녕

두둥맨1 연주하다.

두두둥~~~

피아노맨2 음악가: 안녕

피아노맨2 연주하다.

딩동댕 ♩♪♬

두둥맨2 음악가: 안녕

두둥맨2 연주하다.

두두둥~~~

반응형