파생 클래스
상속(inheritance)
상속(inheritance)은 추상화, 캡슐화와 더불어 객체 지향 프로그래밍을 구성하는 중요한 특징 중 하나입니다.
상속은 사용자에게 높은 수준의 코드 재활용성을 제공하며, 클래스 간의 계층적 관계를 구성함으로써 다형성의 문법적 토대를 마련합니다.
클래스 상속(class inheritance)
C++에서 클래스 상속이란 기존에 정의되어 있는 클래스의 모든 멤버 변수와 멤버 함수를 물려받아, 새로운 클래스를 작성하는 것을 의미합니다.
이때 기존에 정의되어 있던 클래스를 기초 클래스(base class) 또는 부모 클래스(parent class), 상위 클래스(super class)라고도합니다.
그리고 상속을 통해 새롭게 작성되는 클래스를 파생 클래스(derived class) 또는 자식 클래스(child class), 하위 클래스(sub class)라고도 합니다.
이와 같은 클래스의 상속은 다음과 같은 장점을 가집니다.
1. 기존에 작성된 클래스를 재활용할 수 있습니다.
2. 공통적인 부분은 기초 클래스에 미리 작성하여, 파생 클래스에서 중복되는 부분을 제거할 수 있습니다.
파생 클래스(derived class)
파생 클래스(derived class)란 기초 클래스의 모든 특성을 물려받아 새롭게 작성된 클래스를 가리킵니다.
C++에서 파생 클래스는 다음과 같은 문법을 통해 선언합니다.
문법
class 파생클래스이름 : 접근제어지시자 기초클래스이름[, 접근제어지시자 기초클래스이름, ...]
{
// 파생 클래스 멤버 리스트
}
접근 제어 지시자는 기초 클래스의 멤버를 사용할 수 있는 파생 클래스의 접근 제어 권한을 설정합니다.
이때 접근 제어 지시자를 생략하면, 파생 클래스의 접근 제어 권한은 private로 기본 설정됩니다.
또한, 쉼표(,)를 사용하여 상속받을 기초 클래스를 여러 개 명시할 수 있습니다.
이때 파생 클래스가 상속받는 기초 클래스가 하나이면 단일 상속(single inheritance)이라 합니다.
만약 여러 개의 기초 클래스를 상속받으면 다중 상속(multiple inheritance)이라고 합니다.
다중 상속에 대한 더 자세한 사항은 C++ 다중 상속 수업에서 확인할 수 있습니다.
파생 클래스의 특징
C++에서 파생 클래스는 다음과 같은 특징을 가지고 있습니다.
1. 파생 클래스는 반드시 자신만의 생성자를 작성해야 합니다.
2. 파생 클래스에는 기초 클래스의 접근할 수 있는 모든 멤버 변수들이 저장됩니다.
3. 파생 클래스는 기초 클래스의 접근할 수 있는 모든 멤버 함수를 사용할 수 있습니다.
4. 파생 클래스에는 필요한 만큼 멤버를 추가할 수 있습니다.
우선 다음과 같은 Person 클래스가 미리 작성되어 있다고 가정합니다.
Person 클래스
class Person
{
private:
string name_;
int age_;
public:
Person(const string& name, int age); // 기초 클래스 생성자의 선언
void ShowPersonInfo();
};
...
Person::Person(const string& name, int age) // 기초 클래스 생성자의 정의
{
name_ = name;
age_ = age;
}
다음은 기존에 작성된 Person 클래스를 상속받는 Student 클래스를 작성하는 예제입니다.
Student 클래스
class Student : public Person {
private:
int student_id_;
public:
Student(int sid, const string& name, int age); // 파생 클래스 생성자의 선언
};
...
Student::Student(int sid, const string& name, int age) : Person(name, age) // 파생 클래스 생성자의 선언
{
student_id_ = sid;
}
위의 예제에서 보듯이 파생 클래스의 생성자는 기초 클래스의 생성자를 사용하고 있습니다.
그 이유는 파생 클래스의 생성자가 기초 클래스의 private 멤버에 접근할 수 없기 때문입니다.
따라서 기초 클래스의 생성자를 사용해야만 기초 클래스의 private 멤버를 초기화할 수 있습니다.
이때 기초 클래스의 생성자를 명시하지 않으면, 프로그램은 기초 클래스의 디폴트 생성자를 사용하게 됩니다.
예제
class Person
{
private:
string name_;
int age_;
public:
Person(const string& name, int age); // 기초 클래스 생성자의 선언
void ShowPersonInfo();
};
class Student : public Person
{
private:
int student_id_;
public:
Student(int sid, const string& name, int age); // 파생 클래스 생성자의 선언
};
실행 결과
길동의 나이는 29살입니다.
파생 클래스의 객체 생성 순서
다음 그림은 파생 클래스의 생성자가 호출되면 수행되는 동작을 설명하고 있습니다.
C++에서 파생 클래스의 객체가 생성되는 순서는 다음과 같습니다.
1. 파생 클래스의 객체를 생성하면, 프로그램은 제일 먼저 기초 클래스의 생성자를 호출합니다.
이때 기초 클래스 생성자는 상속받은 멤버 변수의 초기화를 진행합니다.
2. 그리고서 파생 클래스의 생성자가 호출됩니다.
3. 반대로 파생 클래스의 수명이 다하면, 먼저 파생 클래스의 소멸자가 호출되고, 그 후에 기초 클래스의 소멸자가 호출됩니다.