상속 접근 수준
Coddy C++ 여정의 객체 지향 프로그래밍 섹션에 포함된 레슨 — 104개 중 49번째.
선택하는 상속 유형은 파생 클래스에서 기본 클래스 멤버에 액세스하는 방식에 영향을 미칩니다. C++는 public, protected, private 상속이라는 세 가지 옵션을 제공합니다.
각 유형이 멤버 액세스를 변환하는 방식은 다음과 같습니다:
| 기본 멤버 | public 상속 | protected 상속 | private 상속 |
|---|---|---|---|
| public | public | protected | private |
| protected | protected | protected | private |
| private | 접근 불가 | 접근 불가 | 접근 불가 |
class Base {
public:
int pub;
protected:
int prot;
private:
int priv;
};
class PublicDerived : public Base {
// pub은 public, prot은 protected, priv는 접근 불가입니다
};
class ProtectedDerived : protected Base {
// pub은 protected, prot은 protected, priv는 접근 불가입니다
};
class PrivateDerived : private Base {
// pub은 private, prot은 private, priv는 접근 불가입니다
};공개 상속은 "is-a" 관계를 모델링하며 가장 흔하게 사용됩니다. Dog는 Animal이므로, 외부 코드에서 이를 하나로 취급할 수 있습니다.
Protected 및 private 상속은 "~을 사용하여 구현됨(implemented-in-terms-of)" 관계를 모델링합니다. 이들은 외부 코드로부터 기본 클래스 인터페이스를 숨기며, 상속 관계를 노출하지 않고 구현을 재사용하고자 할 때 유용합니다. private 상속의 경우, 더 하위의 파생 클래스들조차 원래 기본 멤버에 대한 접근 권한을 잃게 됩니다.
챌린지
쉬움간단한 장치 계층 구조를 구축하여 다양한 상속 유형이 멤버 접근성에 어떤 영향을 미치는지 살펴보겠습니다. 기본 Device 클래스와 각각 다른 상속 유형을 사용하는 세 개의 파생 클래스를 만들어 public, protected, private 상속이 멤버 접근을 어떻게 변화시키는지 직접 확인해 보세요.
코드는 두 개의 파일로 구성됩니다:
Device.h: 서로 다른 접근 수준을 가진 세 개의 멤버를 포함하는 기본Device클래스를 정의합니다:- public 멤버
std::string model - protected 멤버
int serialNumber - private 멤버
int internalCode(기본값은 999로 설정) Model: <model>을 출력하는 public 메서드showModel()
그런 다음, 서로 다른 상속 유형을 사용하여
Device로부터 상속받는 세 개의 파생 클래스를 만듭니다:- public 상속을 사용하는
PublicDevice—Serial: <serialNumber>를 출력하는displaySerial()메서드를 추가합니다. - protected 상속을 사용하는
ProtectedDevice—Serial: <serialNumber>를 출력하는displaySerial()메서드를 추가합니다. - private 상속을 사용하는
PrivateDevice—Serial: <serialNumber>를 출력하는displaySerial()메서드를 추가합니다.
각 파생 클래스는 모델 이름과 시리얼 번호를 인자로 받는 생성자를 가져야 하며, 모델 이름은 기본 클래스로 전달하고 시리얼 번호를 설정해야 합니다.
- public 멤버
main.cpp: 두 개의 입력(각각 별도의 줄)을 읽습니다:- 모델 이름 (문자열)
- 시리얼 번호 (정수)
동일한 입력 값을 사용하여 각 파생 유형의 객체를 하나씩 생성합니다. 그런 다음 접근 차이점을 보여줍니다:
PublicDevice의 경우:- 객체에서 직접
showModel()을 호출합니다 (public 상속은 이를 public으로 유지하므로 작동합니다). model에 직접 접근하여Direct model access: <model>을 출력합니다.displaySerial()을 호출합니다.
ProtectedDevice및PrivateDevice의 경우:displaySerial()만 호출합니다 (상속된showModel()과model은 외부에서 더 이상 public으로 접근할 수 없습니다).
출력 형식:
--- PublicDevice --- Model: <model> Direct model access: <model> Serial: <serial> --- ProtectedDevice --- Serial: <serial> --- PrivateDevice --- Serial: <serial>
예를 들어, 입력값이 Laptop과 12345인 경우:
--- PublicDevice ---
Model: Laptop
Direct model access: Laptop
Serial: 12345
--- ProtectedDevice ---
Serial: 12345
--- PrivateDevice ---
Serial: 12345PublicDevice만 상속된 public 멤버에 대한 외부 접근을 허용하는 방식에 주목하세요. 다른 상속 유형은 외부 코드로부터 기본 클래스의 인터페이스를 숨기지만, 파생 클래스는 여전히 자체 메서드를 통해 내부적으로 protected 멤버에 접근할 수 있습니다.
치트 시트
C++는 파생 클래스에서 기본 클래스 멤버에 접근하는 방식을 제어하는 세 가지 상속 유형을 제공합니다:
| 기본 멤버 | public 상속 | protected 상속 | private 상속 |
|---|---|---|---|
| public | public | protected | private |
| protected | protected | protected | private |
| private | 접근 불가 | 접근 불가 | 접근 불가 |
class Base {
public:
int pub;
protected:
int prot;
private:
int priv;
};
class PublicDerived : public Base {
// pub은 public, prot은 protected, priv는 접근 불가입니다
};
class ProtectedDerived : protected Base {
// pub은 protected, prot은 protected, priv는 접근 불가입니다
};
class PrivateDerived : private Base {
// pub은 private, prot은 private, priv는 접근 불가입니다
};Public 상속은 "is-a" 관계를 모델링하며 가장 일반적입니다. 외부 코드는 파생 클래스를 통해 기본 클래스의 public 멤버에 접근할 수 있습니다.
Protected 및 private 상속은 "implemented-in-terms-of" 관계를 모델링합니다. 이들은 외부 코드로부터 기본 클래스의 인터페이스를 숨깁니다. private 상속의 경우, 더 하위의 파생 클래스조차 원래 기본 멤버에 대한 접근 권한을 잃게 됩니다.
직접 해보기
#include <iostream>
#include <string>
#include "Device.h"
using namespace std;
int main() {
// 입력 읽기
string modelName;
int serialNum;
getline(cin, modelName);
cin >> serialNum;
// TODO: 입력된 값으로 각 파생 타입의 객체 생성
// PublicDevice pubDev(modelName, serialNum);
// ProtectedDevice protDev(modelName, serialNum);
// PrivateDevice privDev(modelName, serialNum);
// TODO: PublicDevice 접근 시연
cout << "--- PublicDevice ---" << endl;
// - 객체에서 직접 showModel() 호출
// - model에 직접 접근하여 출력: Direct model access: <model>
// - displaySerial() 호출
// TODO: ProtectedDevice 접근 시연
cout << "--- ProtectedDevice ---" << endl;
// - displaySerial()만 호출 (showModel과 model은 공개적으로 접근할 수 없음)
// TODO: PrivateDevice 접근 시연
cout << "--- PrivateDevice ---" << endl;
// - displaySerial()만 호출 (showModel과 model은 공개적으로 접근할 수 없음)
return 0;
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.