IS - A 관계


상속으로 클래스의 관계를 구성하기 위해서는 조건이 필요하다. 그리고 조건과 그에 따른 필요가 충족되지 않으면, 상속은 하지 않는 것만 못하다.


상속을 위한 기본 조건인 IS-A 관계의 성립.


무선 전화기는 일종의 전화기 입니다.

무선 전화기 is a 전화기


노트북 컴퓨터는 일종의 컴퓨터입니다.

노트북컴퓨터 is a 컴퓨터


즉, 상속관계가 성립되려면 기초 클래스와 유도 클래스간에 IS-A 관계가 성립해야 한다. 만약에 이 상속관계로 묶고자 하는 두 클래스가 IS-A 관계로 표현되지 않는다면, 이는 적절한 상속의 관계가 아닐 확률이 매우 높은 것이니, 신중한 판단이 필요하다.


#include <iostream>

#include <cstring>

using namespace std;


class Computer

{

    private:

        char owner[50];

    public:

        Computer(char* name)

        {

            strcpy(owner, name);

        }

        void Calculate(void) const

        {

            cout<<"요청 내용을 계산합니다."<<endl;

        }

};


class NotebookComp :public Computer

{

    private:

        int battery;

    public:

        NotebookComp(char* name, int chag)

            : Computer(name), battery(chag)

        {}

        void Charging() {battery+=5;}

        void UseBattery() {battery-=1;}

        void MovingCal()

        {

            if(GetBatteryInfo() < 1)

            {

                cout<<"충전이 필요합니다."<<endl;

                return;

            }

            cout<<"이동하면서 ";

            Calculate();

            UseBattery();

        }

        int GetBatteryInfo(void) {return battery;}

};


class TabletNotebook :public NotebookComp

{

    private:

        char penModel[50];

    public:

        TabletNotebook(char* name, int chag, char* pen)

            :NotebookComp(name, chag)

        {

            strcpy(penModel, pen);

        }

        void Write(char* penInfo)

        {

            if(GetBatteryInfo() < 1)

            {

                cout<<"충전필요"<<endl;

                return;

            }

            if(strcmp(penModel, penInfo) != 0)

            {

                cout<<"등록된 펜이 아니야"<<endl;

                return;

            }

            cout<<"필기내용 처리한다"<<endl;

            UseBattery();

        }

};


int main(void)

{

    NotebookComp nc("qwersd", 5);

    TabletNotebook tn("sdfdfdd", 5, "123");


    nc.MovingCal();

    tn.Write("123");


    return 0;

}


NotebookComp(노트북 컴퓨터)는 Computer(컴퓨터)이다.
TabletNotebook(타블렛 컴퓨터)는 NotebookComp(노트북 컴퓨터)이다.

다음의 관계도 성립이 된다.
TabletNotebook(타블렛 컴퓨터)는 Computer(컴퓨터)이다.

때문에 IS-A 관계의 관점에서만 보면 위 클래스들의 상속관계는 적절하다고 볼 수 있다.

UML(Unified Modeling Language) 의 상속 표현.

Computer
                                                       ↑   class NotebookComp :public Computer
NotebookComp
                                                              ↑   class TabletNotebook :public NotebookComp
TabletNotebook





HAS - A 관계

※ has-a 관계도 상속의 조건은 되지만 복합 관계로 이를 대신하는 것이 일반적.

is-a 관계 외에도 상속이 형성될만한 관계가 "소유의 관계(has-a)" 이다.
경찰이 총을 소유한다. 
경찰 has a 총.

#include <iostream>
#include <cstring>
using namespace std;

class Gun
{
private:
int bullet;
public:
Gun(int bnum) :bullet(bnum)
{ }
void Shut(void)
{
cout<<"BBANG!"<<endl;
bullet--;
}
};

class Police
{
private:
int handcuffs;
Gun* pistol;
public:
Police(int bnum, int bcuff)
: handcuffs(bcuff)
{
if(bnum > 0)
pistol = new Gun(bnum);
else
pistol = NULL;
}
void PutHandcuff(void)
{
cout<<"SNAP!"<<endl;
handcuffs--;
}
void Shut(void)
{
if(pistol==NULL)
cout<<"Hut BBAND!"<<endl;
else
pistol->Shut();
}
~Police(void)
{
if(pistol != NULL)
delete pistol;
}
};

int main(void)
{
Police pman(4, 3);
pman.Shut();
pman.PutHandcuff();

return 0;
}

상속으로 묶인 두 개의 클래스는 강한 연관성을 띤다. 즉, Gun 클래스를 상속하는 Police 클래스로는 총을 소유하는 경찰만 표현 가능하다. 하지만 바로 위의 예제에서는 멤버변수 pistol을 NULL로 초기화함으로써 권총을 소유하지 않은 경찰을 매우 간단히 표현하였다. 
그리고 만약 전기봉을 소유하는 경찰의 표현을 위해서 Police 클래스를 확장하는 것도 어렵지 않다. 전기봉을 표현하는 객체를 참조하는 멤버변수만 하나 추가하면 되기 때문이다.

※ 상속은 IS-A 관계의 표현에 매우 적절하다. 그리고 경우에 따라서는 HAS-A 관계의 표현에도(소유 관계의 표현에도) 사용될 수 있으나, 이는 프로그램의 변경에 많은 제약을 가져다 줄 수 있다.

Posted by scii
: