OOP들 개념에 상속의 등장이라

invisible_thorn·2024년 9월 10일
0
post-thumbnail

[씹어먹는 C++] https://modoocode.com/210 참고

상속이 왜 필요할까?

물론 중복코드를 방지하기 위한 것도 있지만! 실제 이유는 상속이라는 기능을 통해 객체지향프로그래밍에서 추구하는 실제 객체의 추상화를 좀 더 효과적으로 할 수 있게 되었다고 한다.

C에서는 할 수 없었던 구조체 간의 관계표현을 C++에서는 상속으로 클래스 사이의 관계를 표현할 수 있게 된것이다!

class Manager : public Employee
  1. Manager 클래스는 Employee 의 모든 기능을 포함한다.

  2. Manager 클래스는 Employee 의 기능을 모두 수행할 수 있기 때문에 (Manager 에게는 약간 기분 나쁘겠지만) Manager 를 Employee 라고 칭해도 무방하다.

  3. 즉, 모든 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)와 함께 알아보도록 하자.ㅇㅅㅇ

0개의 댓글

관련 채용 정보