자료 저장소

# 상속(Inheritance)

"UnivStudent 클래스가 Person 클래스를 상속한다"

UnivStudent 클래스가 Person 클래스를 상속하게 되면, UnivStudent 클래스는 Person 클래스가 지니고 있는
모든 멤버를 물려받는다. 즉, UnivStudent 객체에는 UnivStudent 클래스에 선언되어있는 멤버뿐만 아니라 Person
클래스에 선언되어 있는 멤버도 존재하게 된다.


# 상속의 문법적 이해

#include <iostream> 
#include <cstring>
usingnamespacestd;

class Person
{
private:
int age; // 나이
char name[50]; // 이름
public:
Person(int myage, char * myname) : age(myage)
{
strcpy(name, myname);
}
void WhatYourName() const
{
cout<<"My name is "<<name<<endl;
}
void HowOldAreYou() const
{
cout<<"I'm "<<age<<" years old"<<endl;
}
};

class UnivStudent : public Person // Person 클래스를 상속한다
{
private:
char major[50]; // 전공과목
public:
UnivStudent(char * myname, int myage, char * mymajor)
: Person(myage, myname) // 상속받은 기초클래스의 생성자를 호출
{
strcpy(major, mymajor);
}
void WhoAreYou() const
{
WhatYourName();
HowOldAreYou();
cout<<"My major is "<<major<<endl<<endl;
}
};

int main(void)
{
UnivStudent ustd1("Lee", 22, "Computer eng.");
ustd1.WhoAreYou();

UnivStudent ustd2("Yoon", 21, "Electronic eng.");
ustd2.WhoAreYou();
return0;
};
※ 용어 정리
상위 클래스 ↔ 하위 클래스
기초 클래스 ↔ 유도 클래스
슈퍼 클래스 ↔ 서브 클래스
부모 클래스 ↔ 자식 클래스


※ 유도 클래스의 객체가 소멸될 때에는, 유도 클래스의 소멸자가 실행되고 난 다음에 기초 클래스의 소멸자 실행.
※ 상속 받은 클래스라 하더라도 자신의 멤버는 자신이 초기화하고 소멸하는 것이 기본이다.



# 세 가지 형태의 상속

■ protected 상속
class Derived : protected Base { ... } 

protected보다 접근 범위가 넓은 멤버는 protected로 변경시켜서 상속한다.

■ private 상속
class Derived : private Base { ... } 

private보다 접근 범위가 넓은 멤버는 private로 변경시켜서 상속한다. 모든 멤버가 접근불가이므로 의미없다.

■ public 상속
class Derived : public Base { ... } 

public보다 접근 범위가 넓은 멤버는 public로 변경시켜서 상속한다. C++의 상속은 public 뿐이라고 생각하자.
다중상속과 같이 특별한 경우가 아니면 public 이외의 상속은 잘 사용하지 않는다.


※ 상속의 잘못된 관점
"상속은 기존에 정의해 놓은 클래스의 재활용을 목적으로 만들어진 문법적 요소가 상속이다."
상속은 재활용을 위해 만들어진 것이 아니다.


# 상속의 조건

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


■ IS-A 관계의 상속 (일종의~이다.)

class Student : public Person

학생은 일종의 사람이다.

class Notebook : public Computer

노트북은 일종의 컴퓨터 이다.

유도클래스는 기초클래스의 모든 특성을 포함하면서 +@의 특성이 추가되기 때문에 IS-A 관계로 상속을 표현한다.

※ IS-A관계가 성립될때 상속받은 클래스는 밑으로 내려갈수록 그 특성이 많아지고(기능확대) 범위는 축소된다.
반대로 위로 올라갈수록 그 특성은 일반화 되어간다.(특성이 줄어들고 범위가 넓어진다)

※ 만약, "사람은 일종의 학생이다" 라고 상속관계를 표현하게 되면 모든 사람은 학생이여야 하는 현실세계와 전혀
동떨어진 프로그램이 되버린다.

■ HAS-A 관계의 상속 (소유)

class Police : public cudgel

경찰은 몽둥이를 소유한다.

이 경우는 HAS-A 관계로 상속이 표현 가능하다. 하지만, HAS-A관계의 상속은 포함관계를 통해 표현할 수 있다.

■ HAS-A에 의한 상속 그리고 대안

- 포함관계를 통해서 소유 관계를 표현
- 객체 멤버에 의한 포함관계를 형성
- 객체 포인터 멤버에 의한 포함관계를 형성

class Cudgel 
{
public :
void swing() { }
}

class Police
{
private:
Cudgel cud;
// 클래스의 객체가 멤버로 포함되기 위해서는 void 생성자를 멤버로 지녀야 한다.
Cudgel *cud;
// 포인터로도 포함관계를 형성할 수 있다.
public:
void weapon() { }
}
※ 상속으로 묶인 두 개의 클래스는 강한 연관성(결합도(coupling))을 띤다. 만약 소유관계의 상속에서 경찰이
몽둥이를 가지지 않은 경찰을 표현하기 위해서는 클래스의 구조 자체가 바뀌어야 한다. 하지만 이를 포함관계로
구성하면 cud에 NULL을 대입하므로써 간단히 표현이 가능해진다.

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


 
댓글 로드 중…

최근에 게시된 글