상속: 객체 지향 프로그래밍의 재활용과 확장
상속의 개념
상속은 객체 지향 프로그래밍 (OOP)의 핵심 개념 중 하나로, 기존 클래스의 속성과 메서드를 물려받아 새로운 클래스를 생성하는 것을 의미한다. 상속을 통해 코드 재사용성을 높이고, 클래스 간의 관계를 계층적으로 표현할 수 있다.
interitance |
상속, 왜 필요할까?
상속은 다음과 같은 이유로 필요하다.
- 코드 재사용: 기존 클래스의 코드를 재사용하여 새로운 클래스를 생성할 수 있다. 이는 개발 시간을 단축하고 코드의 유지보수성을 향상시킨다.
- 계층적 구조: 클래스 간의 관계를 계층적으로 표현하여 코드의 가독성을 높인다.
- 다형성: 상속은 다형성을 구현하는 데 중요한 역할을 한다. 다형성은 동일한 이름의 메서드가 객체의 유형에 따라 다르게 동작하는 것을 의미한다. (지난 시간 참조)
상속, 언제 사용할까?
두 객체 사이에 "is-a" 관계가 성립할 때 상속을 사용한다. 예를 들어, "학생은 사람이다"라는 관계가 성립하므로, Student
클래스는 Person
클래스를 상속할 수 있다.
상속의 문법
C++에서 상속은 다음과 같은 문법을 사용한다.
class DerivedClass: public BaseClass {
// 멤버 변수 및 메서드
};
DerivedClass
는 상속받는 클래스이고, BaseClass
는 상속하는 클래스이다. public
은 상속 유형을 나타낸다.
상속 유형
상속 유형은 기본 클래스의 멤버에 대한 접근 권한을 결정한다. C++에서는 다음과 같은 세 가지 상속 유형을 제공한다.
- public 상속: 기본 클래스의 public 멤버는 파생 클래스에서 public 멤버로, protected 멤버는 protected 멤버로 유지된다.
- protected 상속: 기본 클래스의 public 멤버와 protected 멤버는 파생 클래스에서 protected 멤버로 유지된다.
- private 상속: 기본 클래스의 public 멤버와 protected 멤버는 파생 클래스에서 private 멤버로 유지된다.
이제 예제를 통해 자세히 살펴보도록 하겠다.
예시
class Base {
private:
int m_private;
protected:
int m_protected;
public:
int m_public;
int GetPrivate() { return m_private; }
};
class Derived : public Base {
public:
void AccessMembers() {
// m_private = 10; // Error: private 멤버에 직접 접근 불가
m_protected = 20; // OK: protected 멤버에 접근 가능
m_public = 30; // OK: public 멤버에 접근 가능
int privateValue = GetPrivate(); // OK: public 멤버 함수를 통해 private 멤버에 접근
}
};
위 코드에서 Derived
클래스는 Base
클래스의 private
멤버인 m_private
에 직접 접근할 수 없다. 그러나 Base
클래스가 제공하는 public
멤버 함수인 GetPrivate()
을 통해 m_private
값을 얻을 수 있다.
상속 위계의 중요성
한편, 상속은 클래스 간의 계층적 관계를 나타내기 때문에, 상속 위계를 유지하는 것이 중요하다. 상속 위계를 유지하지 않으면 코드의 가독성이 떨어지고, 예상치 못한 동작이 발생할 수 있다.
다음 예제는 상속 위계를 유지하지 않은 경우 발생하는 문제를 보여준다.
class Person {
public:
void Eat() { cout << "Eat" << endl; }
};
class Student: public Person {
public:
void Study() { cout << "Study" << endl; }
};
class Teacher: public Person {
public:
void Teach() { cout << "Teach" << endl; }
};
int main() {
Student s1;
Teacher t1;
Person* p_arr[] = { &s1, &t1 };
for (int i=0; i<2; i++) {
p_arr[i]->Study(); // Error: Person 클래스에는 Study 메서드가 없다.
}
return 0;
}
위 코드에서 Person
클래스에는 Study
메서드가 없기 때문에, p_arr[i]->Study()
호출은 에러를 발생시킨다.
마치며
이번 포스팅에서는 상속의 개념, 필요성, 사용 시점, 문법, 상속 유형, 상속 위계의 중요성에 대해 알아보았다. 기본적인 부분에 대해 다뤘으니 다음 시간에는 생성자, 소멸자 등 상속에 대해 더 자세히 알아보고자 한다.
추천글:
[C++][OOP] Polymorphism - operator overloading
(https://hyeondev.blogspot.com/2024/10/coop-polymorphism-operator-overloading.html)
[C++][OOP] Class - definition, struct, constructor, destructor
(https://hyeonb.blogspot.com/2024/10/coop-class-definition-struct.html)
[C++][OOP] Class - UML diagram, relationship
(https://hyeondev.blogspot.com/2024/10/coop-class-uml-diagram-relationship.html)