티스토리 뷰

상속 (Inheritance)

 

클래스를 다른 클래스에 물려주는 것

 

C++에서 상속은 객체 지향 프로그래밍(OOP)의 중요한 개념 중 하나이며, 그 개념은 크게 어렵지는 않다. 상속은 기존 클래스(부모 클래스 또는 기본 클래스)의 특성과 동작을 새로운 클래스(자식 클래스 또는 파생 클래스)에게 물려주는 메커니즘을 제공한다. 이를 통해 코드의 재사용성을 높이고 계층적인 구조를 형성하여 프로그램의 구성을 용이하게 만들 수 있다.

 

상속이 일어나면 접근 제어자에 따라 부모 클래스의 멤버들을 자식 클래스가 참조할 수 있게되고, 자식 클래스는 자신만의 멤버를 더 선언할 수 있다.  또한, 자식 클래스는 부모 클래스의 파생된 클래스가되어 자식 클래스가 부모 클래스에 포함되는 관계를 형성한다. 혹은 자식 클래스는 부모 클래스의 일종이라 부를 수 있다.

 

 

위와 같이 자동차라는 카테고리 안에 세부 자동차 종류가 나뉘는 것과 같이 자동차가 공통으로 가지는 값을 부모 클래스에 선언되고 각 자식 클래스(파생 클래스)는 본인의 역할에 맞는 추가적인 멤버가 선언될 수 있다.

 

자동차 클래스와 파생 클래스들
#include <iostream>
#include <string>

using namespace std;

// 기본 차량 클래스
class Vehicle {
public:
    int fuelCapacity;
    int mileage;
    string model;

public:
    Vehicle(const string& model, int fuelCapacity, int mileage)
        : model(model), fuelCapacity(fuelCapacity), mileage(mileage) {}

    void DisplayInfo() const {
        cout << "Vehicle 정보 - Model: " << model
             << ", FuelCapacity: " << fuelCapacity
             << ", Mileage: " << mileage << endl;
    }

    virtual void Honk() const {
        cout << "빵빵!" << endl;
    }
};

// 자동차 클래스 (Vehicle을 상속받음)
class Car : public Vehicle {
public:
    string manufacturer;
    bool convertible;

public:
    Car(const string& manufacturer, const string& model, int fuelCapacity, int mileage, bool convertible)
        : Vehicle(model, fuelCapacity, mileage), manufacturer(manufacturer), convertible(convertible) {}

    void Drift() const {
        cout << "차를 드리프트한다!" << endl;
    }

    // 오버라이딩된 함수
    void Honk() const override {
        cout << "자동차가 빵빵 울린다!" << endl;
    }
};

// 트럭 클래스 (Vehicle을 상속받음)
class Truck : public Vehicle {
public:
    int loadCapacity;

public:
    Truck(const string& model, int fuelCapacity, int mileage, int loadCapacity)
        : Vehicle(model, fuelCapacity, mileage), loadCapacity(loadCapacity) {}

    void Carry() const {
        cout << "트럭이 짐을 싣다." << endl;
    }

    // 오버라이딩된 함수
    void Honk() const override {
        cout << "트럭이 큰 소리로 경적을 울린다!" << endl;
    }
};

int main() {
    // 자동차 객체 생성
    Car myCar("Toyota", "Camry", 50, 25, true);
    myCar.DisplayInfo();
    myCar.Honk();
    myCar.Drift();

    cout << endl;

    // 트럭 객체 생성
    Truck myTruck("Ford", "Pickup", 70, 15, 500);
    myTruck.DisplayInfo();
    myTruck.Honk();
    myTruck.Carry();

    return 0;
}

 

위 코드는 자동차라는 부모 클래스(=기본 클래스, 슈퍼 클래스, 베이스 클래스)를 받은 자식 클래스(=파생 클래스)들이 각자 트럭과 일반 차량으로 선언되어 자신만의 멤버가 선언되는 예제이다.

 


상속 접근 제어자

상속 관계에서는 접근 제어자(access specifiers)인 public, protected, private는 자식과 부모 클래스 그리고 외부 사이 접근을 제어할 수 있다. 각각의 접근 제어자는 파생 클래스(자식 클래스)가 기본 클래스(부모 클래스)의 멤버들에 어떻게 접근할 수 있는지를 결정한다.

 

접근 제어자 외부 접근 자식 클래스에서 접근 부모 클래스 내부에서 접근
public 가능 가능 가능
protected 불가능 가능 가능
private 불가능 불가능

 

  • public 제어자는 외부와 내부 그리고 자식 클래스의 접근이 가능한 열려있는 구문이다.
  • private 제어자는 외부와 자식 클래스가 접근이 불가능한 구문이다.
  • protected 제어자는 외부만 접근이 불가능한 구문이다.

 

여기서 주목해볼 접근제어자는 바로 protected 접근 제어자이다. protected 제어자는 상속 받은 자식 클래스만 접근이 가능한 접근 제어자이다. 

 

상속 제어자 예시
#include <iostream>
#include <string>

using namespace std;

// 기본 클래스
class Base {
public:
    int publicVar;
    int getPrivate() { return privateVar; }

protected:
    int protectedVar;

private:
    int privateVar;

public:
    Base() : publicVar(1), protectedVar(2), privateVar(3) {}

    void Display() const {
        cout << "Base 클래스 - publicVar: " << publicVar
             << ", protectedVar: " << protectedVar
             << ", privateVar: " << privateVar << endl;
    }
};

// public 상속
class PublicDerived : public Base {
public:
    void AccessBaseMembers() const {
        // publicVar에는 접근 가능
        cout << "PublicDerived 클래스 - publicVar: " << publicVar << endl;

        // protectedVar에는 접근 가능
        cout << "PublicDerived 클래스 - protectedVar: " << protectedVar << endl;

        // privateVar에는 접근 불가능
        // 단, public 함수를 통해 접근 가능
        cout << "PublicDerived 클래스 - privateVar: " << getPrivate() << endl;
    }
};

int main() {
    // public 상속
    PublicDerived publicObj;
    publicObj.AccessBaseMembers();

    return 0;
}

 

위 코드에서 자식 클래스인 'PublicDerived' 클래스는 부모 클래스를 상속 받아 각 public, protected 변수에 직접 접근이 가능하다. 하지만 private 변수는 public으로 선언된 getPrivate()함수를 통해서만 접근이 가능했다. 즉, private 멤버들은 자식 클래스에 상속이 되지만 실제로 접근만 불가능하다.

 

 

상속 모드

위에서 상속 제어자에 대해 공부를 하며, 상속되는 과정에서 부모 클래스를 public으로 상속 받는 것을 보았다. 이는 상속 모드라는 것으로, 상속 모드는 기본 클래스의 멤버들이 파생 클래스에서 어떻게 상속되는지 및 접근 가능한 범위를 제어하는 역할을 한다. 각 상속 모드는 상속된 멤버들의 접근 권한을 결정하며, 이로써 파생 클래스에서 어떤 범위에서 기본 클래스의 멤버에 접근할 수 있는지를 결정한다.

 

공개 상속

public으로 상속 모드를 설정할 경우, 부모 클래스 멤버의 접근 제어를 그대로 사용한다. 즉, 부모 클래스의 public 멤버는 자식 클래스에도 public이고, 부모의 protected는 자식의 protected가 된다. 부모의 private은 애초에 접근이 불가능하다.

 

부모 상속 자식
public 멤버 >> public 접근
protected 멤버 >> protected 접근
private 멤버 X 접근 불가

 

보호 상속

protected로 상속 모드를 설정할 경우, 부모 클래스 모든 접근 제어를 protected로 변경한다. 즉, 부모의 public과 protected 모두 자식은 protected로 생각하는 것이다. 여전히 private은 원래 접근이 불가능하다.

 

부모 상속 자식
public 멤버 >> protected 접근
protected 멤버
private 멤버 X 접근 불가

 

비공개 상속

private로 상속 모드를 설정할 경우, 부모 클래스 모든 접근 제어가 private으로 변경된다. 즉, 부모 클래스의 모든 값에 접근이 불가능해 진다.

 

부모 상속 자식
public 멤버 X 접근 불가
protected 멤버
private 멤버

 

 

 

 

 

 

 

'Computer Language > C & C++' 카테고리의 다른 글

[C++] 상속 3) 상속의 필요성  (0) 2023.12.19
[C++] 상속 2) 상속 관계의 생성/소멸자  (0) 2023.12.19
[C++] 상수형 메서드  (0) 2023.12.18
[C++] 정적 멤버  (1) 2023.12.18
[C++] 깊은 복사와 얕은 복사  (0) 2023.12.14
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함