[씹어먹는 C++] https://modoocode.com/210 참고
물론 중복코드를 방지하기 위한 것도 있지만! 실제 이유는 상속이라는 기능을 통해 객체지향프로그래밍에서 추구하는 실제 객체의 추상화를 좀 더 효과적으로 할 수 있게 되었다고 한다.
C에서는 할 수 없었던 구조체 간의 관계표현을 C++에서는 상속으로 클래스 사이의 관계를 표현할 수 있게 된것이다!
class Manager : public Employee
Manager 클래스는 Employee 의 모든 기능을 포함한다.
Manager 클래스는 Employee 의 기능을 모두 수행할 수 있기 때문에 (Manager 에게는 약간 기분 나쁘겠지만) Manager 를 Employee 라고 칭해도 무방하다.
즉, 모든 Manager 는 Employee 이다.
이러한 관계는 위와 같은 모습으로 표현된다. (파생 클래스가 기반 클래스를 화살표로 가리키기)
파생되면 파생될 수록 더 구체화되고, 기반 클래스로 올라갈 수록 일반화 된다고 말한다.
#include <iostream>
#include <string>
class Base {
std::string s;
public:
Base() : s("기반") { std::cout << "기반 클래스" << std::endl; }
void what() { std::cout << s << std::endl; }
};
class Derived : public Base {
std::string s;
public:
Derived() : s("파생"), Base() { std::cout << "파생 클래스" << std::endl; }
void what() { std::cout << s << std::endl; }
};
int main() {
std::cout << " === 기반 클래스 생성 ===" << std::endl;
Base p;
p.what();
std::cout << " === 파생 클래스 생성 ===" << std::endl;
Derived c;
c.what();
return 0;
}
이때 출력 결과를 보면
===기반 클래스 생성===
기반 클래스
기반
===파생 클래스 생성===
기반 클래스
파생 클래스
파생
이렇게 Base를 상속받는 Derived 클래스에서 what을 호출하면 Derived의 what이 Base의 what을 오버라이드 해서 Derived의 what이 호출되게 한다!
다음 예시도 살펴보자
#include <iostream>
#include <string>
class Base {
std::string s;
public:
Base() : s("기반") { std::cout << "기반 클래스" << std::endl; }
void what() { std::cout << s << std::endl; }
};
class Derived : public Base {
std::string s;
public:
Derived() : s("파생"), Base() { std::cout << "파생 클래스" << std::endl; }
void what() { std::cout << s << std::endl; }
};
int main() {
Base p;
Derived c;
std::cout << "=== 포인터 버전 ===" << std::endl;
Base* p_c = &c;
p_c->what();
return 0;
}
실행 결과를 확인해보면
기반 클래스
기반 클래스
파생 클래스
===포인터 버전===
기반
Base* p_c = &c;
Base와 Derived는 다른 클래스니까 가능한가? 싶겠지만
Derived는 Base를 상속 받고 있기 때문에 가능하다!(Derived is a Base) // is-a 관계
이와 같은 그림처럼,
Derived를 Base로 업캐스팅 하여 나타낼 때는 Base 부분만을 가지고 있기 때문에 '기반'을 출력하게 된다.
이는 단순히 집합 관계처럼 필요, 충분 조건을 생각해보면 된다.
따라서 오류가 발생한다.
음, 이와 관련있는 static_cast와 dynamic_cast는 다음에 또 다뤄보도록 하겠다 *^^*
그렇다면 상속받은 기반 클래스를 출력하지 않고 파생 클래스를 그대로 출력하기 위해서는 어떻게 해야할까?
이는 뒤에서 가상 함수(virtual)와 함께 알아보도록 하자.ㅇㅅㅇ