반응형
상속(inheritance)이란?
- “일정한 친족적 관계가 있는 사람 사이에 한 쪽이 사망하거나 법률상의 원인이 발생하였을 때 재산적 또는 친족적 권리와 의무를 계승하는 제도” 라고 네이버 사전에 정의되어 있다.
- 부모님이 돌아가시면 부모님의 재산을 모두 물려받게 됨.
- 그런데 이 상속이 C++에서도 존재함.
예를 들어서 설명해보자.
- 사람이란 클래스, 학생이란 클래스가 있다고 가정
- 사람이란 클래스 내에는 이름, 나이, 취미 등과 같은 속성과 함께, 일어나기, 잠자기, 먹기, 공부하기 등 행동이 정의되어 있음.
- 학생이란 클래스 내에는 마찬가지로 이름, 나이, 취미, 소속, 학교와 같은 속성, 잠자기, 먹기, 공부하기 등과 같은 행동으로 정의되어 있음.
- 그런데, 학생도 역시 사람이란 부류에 속하므로 학생은 사람에 포함됨.
- 사람 클래스와 학생 클래스가 공통적으로 가지는 속성(이름, 나이, 취미 …)을 보면 학생 클래스 내에서 따로 정의, 선언할 필요 없이 사람 클래스 내의 속성, 행동들을 물려받아 쓰면 됨.
- 코드의 양도 줄어들고, 프로그램의 유연성이 높아지는 등 여러가지 이점이 있음.
상속 살펴보자
→ C++에서 클래스를 상속하는 것은 아래와 같다. 그저 클래스를 상속시키려면 상속받을 클래스의 이름 옆에 :와 접근 제한자, 그리고 상속할 클래스의 이름을 붙여주면 됨.
..
class 클래스명 {
// ..
}
class 클래스명 : 접근제한자 클래스명
{
// ..
}
..
→ 접근 제한자는 public, private, protected가 들어가게 됨.
상속을 구현해보자
#include <iostream>
using namespace std;
class Human {
private:
int age;
char name[10];
char hobby[20];
public:
Human(int _age, char * _name, char * _hobby) : age(_age)
{
strcpy(name, _name);
strcpy(hobby, _hobby);
}
void getup()
{
cout << "기상!" << endl;
}
void sleep()
{
cout << "취침!" << endl;
}
void eat()
{
cout << "식사!" << endl;
}
void study()
{
cout << "공부!" << endl;
}
void showInfo()
{
cout << "이름: " << name << endl;
cout << "나이: " << age << endl;
cout << "취미: " << hobby << endl;
}
};
class Student : public Human {
private:
char school[30];
public:
Student(int _age, char * _name, char * _hobby, char * _school) : Human(_age, _name, _hobby)
{
strcpy(school, _school);
}
void schoolInfo()
{
showInfo();
cout << "소속 학교: " << school << endl;
}
};
int main()
{
Student stu(18, "김철수", "프로그래밍", "자바고등학교");
stu.schoolInfo();
stu.getup();
stu.eat();
stu.study();
stu.sleep();
return 0;
}
결과
💡
이름: 김철수
나이: 18
취미: 프로그래밍
소속 학교: 자바고등학교
기상!
식사!
공부!
취침!
private, protected, public 상속
- private는 외부에서 접근이 불가능하며, protected는 외부에서 접근이 불가능 하나 파생 클래스에서는 접근이 가능하고, public는 어디서나 접근이 가능함.
private 상속을 보자
#include <iostream>
using namespace std;
class Parent
{
private:
int num1;
public:
int num2;
protected:
int num3;
};
class Base : private Parent { };
int main()
{
Base base;
cout << base.num1 << endl; // error!
cout << base.num2 << endl; // error!
cout << base.num3 << endl; // error!
return 0;
}
값을 들고오는 코드도 보자
#include <iostream>
using namespace std;
class Parent
{
private:
int num1;
public:
int num2;
protected:
int num3;
};
class Base : private Parent
{
public:
Base()
{
num2 = 1;
num3 = 2;
cout << this->num2 << endl; // error!
cout << this->num3 << endl; // error!
};
int getNum2()
{
return num2;
};
int getNum3()
{
return num3;
};
};
int main()
{
Base base;
cout << base.getNum2() << endl; // error!
cout << base.getNum3() << endl; // error!
return 0;
}
중요한 것은!!
- 값을 함수로 통해 접근은 할 수 있지만 바로 접근하지 못 한다는 것 왜? 전부 private이기 때문.
- private 상속을 하게 되면 private 제한자보다 접근 범위가 넓은 멤버는 모두 private 제한자로 바꾸어 상속하는 것이기 때문. 즉 private보다 접근 범위가 넓은 (public, protected) 멤버들은 모조리 private로 바꾸어서 넘어가는 것임.
protected 상속
#include <iostream>
using namespace std;
class Parent
{
private:
int num1;
public:
int num2;
protected:
int num3;
};
class Base : protected Parent { };
int main()
{
Base base;
cout << base.num1 << endl; // error!
cout << base.num2 << endl; // error!
cout << base.num3 << endl; // error!
return 0;
}
결과
protected상속.cpp:20:10: error: cannot cast 'Base' to its protected base
class 'Parent'
cout << base.num1 << endl; // error!
^
protected상속.cpp:15:14: note: declared protected here
class Base : protected Parent { };
^~~~~~~~~~~~~~~~
protected상속.cpp:20:15: error: 'num1' is a private member of 'Parent'
cout << base.num1 << endl; // error!
^
protected상속.cpp:8:6: note: declared private here
int num1;
^
protected상속.cpp:21:10: error: cannot cast 'Base' to its protected base
class 'Parent'
cout << base.num2 << endl; // error!
^
protected상속.cpp:15:14: note: declared protected here
class Base : protected Parent { };
^~~~~~~~~~~~~~~~
protected상속.cpp:21:15: error: 'num2' is a protected member of 'Parent'
cout << base.num2 << endl; // error!
^
protected상속.cpp:15:14: note: constrained by protected inheritance here
class Base : protected Parent { };
^~~~~~~~~~~~~~~~
protected상속.cpp:10:6: note: member is declared here
int num2;
^
protected상속.cpp:22:10: error: cannot cast 'Base' to its protected base
class 'Parent'
cout << base.num3 << endl; // error!
^
protected상속.cpp:15:14: note: declared protected here
class Base : protected Parent { };
^~~~~~~~~~~~~~~~
protected상속.cpp:22:15: error: 'num3' is a protected member of 'Parent'
cout << base.num3 << endl; // error!
^
protected상속.cpp:12:6: note: declared protected here
int num3;
^
6 errors generated.
값을 들고오는 코드
- 보면 알 수 있듯이, Base 클래스에서 num2, num3는 바로 값을 넣을 수 있다
- private은 접근하지 못 한다.
#include <iostream>
using namespace std;
class Parent
{
private:
int num1;
public:
int num2;
protected:
int num3;
};
class Base : protected Parent
{
public:
Base()
{
num2 = 1;
num3 = 2;
cout << this->num2 << endl; // error!
cout << this->num3 << endl; // error!
// cout << base.num3 << endl; // error!
};
int getNum3()
{
return num3;
};
};
int main()
{
Base base;
// base.num2 = 2;
// // base.num3 = 3;
// //cout << base.num1 << endl; // error!
// cout << base.num2 << endl; // error!
cout << base.getNum3() << endl; // error!
return 0;
}
public 상속
- 다른 곳에서 바로 접근이 가능하지만 protected와 private은 불가능.
#include <iostream>
using namespace std;
class Parent
{
private:
int num1;
public:
int num2;
protected:
int num3;
};
class Base : public Parent { };
int main()
{
Base base;
cout << base.num1 << endl; // error!
cout << base.num2 << endl; // ok!
cout << base.num3 << endl; // error!
return 0;
}
jaeyojun@c2r10s3 상속 % c++ public상속.cpp
public상속.cpp:20:15: error: 'num1' is a private member of 'Parent'
cout << base.num1 << endl; // error!
^
public상속.cpp:8:6: note: declared private here
int num1;
^
public상속.cpp:22:15: error: 'num3' is a protected member of 'Parent'
cout << base.num3 << endl; // error!
^
public상속.cpp:12:6: note: declared protected here
int num3;
^
2 errors generated.
값을 넣어보는 코드
- 클래스에서 protected는 접근할 수 있지만 private은 접근 불가능
#include <iostream>
using namespace std;
class Parent
{
private:
int num1;
public:
int num2;
protected:
int num3;
};
class Base : public Parent {
public:
Base(){
num2 = 2;
num3 = 1;
cout << num3 << endl; // ok!
}
};
int main()
{
Base base;
//cout << base.num1 << endl; // error!
cout << base.num2 << endl; // ok!
//cout << base.num3 << endl; // error!
return 0;
}
이 분의 블로그 토대로 공부하였습니다.
반응형
'C++ > C++ 상속' 카테고리의 다른 글
C++ 상속 오버라이딩 (1) | 2024.01.24 |
---|