C++ 기초문법 상속
상속 이란, 부모 - 자식 관계 를 객체 화 했다고 하면 되려나?
기본 소스 코드는 이렇다
class AAA //Base 클래스
{
int a;
public:
AAA(){
cout<<"AAA() call!"<<endl;
a=10;
}
AAA(int i){
cout<<"AAA(int i) call!"<<endl;
}
func(){ cout<<"aaa"<<endl;}
};
이는, 부모 클래스 , BASE 클래스라 부른다 !
class BBB : public AAA //Derived 클래스
{
int b
public:
BBB(){
cout<<"BBB() call!"<<endl;
b=20;
}
BBB(int j){
cout<<"BBB(int j) call!"<<endl;
}
func2(){ cout<<"aaa"<<endl;}
};
이는, 상속 받은 클래스, Derived 클래스라 부른다 !
위와 같이 클래스 두개가 생성 되었다고 가정 하고 ,
int main(void) {
BBB b1
return 0;
}
위와 같이 메인 클래스가 되어있다고 가정 한다면,
첫째로, B 클래스 안에, A 클래스가 상속 되어, 메모리 공간이 할당되고
둘째로, BASE 클래스의 생성자가 실행 되며,
셋째로, Derived 클래스의 생성자가 실행 된다.
상속 이라는 개념은,
현실에 있는 상속의 개념을 그대로 대입 한것이라 생각 하면 댄다.
부모는 자식에게 상속 해주어서, 자식은 부모의 모든걸 갖고 있지만,
부모는 자식의 것을 갖지 못한다.
이러한 얘기를 한 이유는, 객체 포인터에 대해 언급 하기 위해서 인데,
예를 들어, AAA 는 BASE 클래스, BBB 는 Derived 클래스라고 가정하고
BBB* a = new BBB;
a->func()
a->func2();
라는 선언이 main 함수에 있다고 한다면, 위의 소스에 대입 해봤을때.
아무 에러 없이 컴파일이 가능 하다.
하지만
BBB* a = new AAA;
a->func()
a->func2();
라는 선언은 문제가 발생한다. 이유는 앞에 말한대로, 부모는 자식에게 상속해주긴 하지만, 자식의 것을 갖지못한다. 즉 자식의 함수를 호출하지 못한다. 자식은 상속 받았기 때문에, 부모의 함수도 호출 할 수 있다.
각 클래스마다 동일한 함수가 존재 할 수 있을 것이다.
func() 와 func2() 는
함수명이 다르지만, 두개를 같은 이름으로 선언 될 수 도 있는데,
그것을 함수오버라이딩 이라 한다.
함수 오버라이딩을 하는 이유는 , 클래스를 스키마 하면서, 위와 같은 상속의 단점을 보안 하기 위해서 함수 오버라이딩을 쓴다.
즉, AAA 클래스에도 func() 함수가 존재 하고,
BBB 라는 클래스에도 func() 함수가 존재 하는 것을 의미하는데
무의미한 func() 라는 함수명을 버리고 , 뜻을 부여 해서 부연 설명을 해보자면,
GetMoney() 라는 함수가 BBB 클래스에 존재 한다 생각 해보자.
BBB 클래스에서는 GetMoney 라는 함수에 접근할 수 있다. 자기꺼니까
AAA 클래스는 접근이 가능한가? 접근할 수 없다. 상속 관계라 할지라도
Derived 것이기 때문이다. 메인 함수에서 AAA 클래스 를 호출 했을때,
Derived 의 함수를 호출 하고자 할때 , 과연 어떻게 해야 할까?
바로 Virtual 키워드와 함수오버라이딩을 사용 하면 된다 .
vitual 키워드는 가상, 즉 존재하지 않는 것이라고 가상화 시킨다.
프로그래머는, BASE 클래스인 AAA 에서, virtual GetMoney 함수를 선언하면, 가상화된 함수이기 때문에, 컴파일러는, 오버라이딩 된 자식의 함수를 호출 하게 된다. 즉 AAA 의 입장에서 BBB Derived 함수를 호출 할 수 있게 되는 것이다.
이렇게 추상화 된 클래스를 추상클래스라 하며
virtual GetMonet()=0; 이라고 명명한 함수는, 순수 가상 함수라 한다.
상속은, 부모는 자식의 함수를 사용하지 못한다는 것을 앞서 언급했는데