도슐랭스타
C++ - 상속성 본문
객체지향 프로그래밍의 중심 기술
- 캡슐화
- 다형성
- 상속성
상속성
- 기존에 정의된 클래스(부모 클래스)의 '속성'과 '메서드'를 새로운 클래스(자식 클래스)가 물려받아 사용하는 것이다.
상속의 장점
- 코드의 재사용성을 높인다. = 코드의 중복을 줄일 수 있다.
- 가독성을 높인다.
- 유지 보수를 용이하게 해준다.
클래스 상속의 형식
- class 파생클래스명 : 상속접근제어 기본클래스명 { ~~ };
class Cat : public Animal {
};
//Animal클래스로부터 public으로 상속받은 Cat클래스
클래스 상속의 예시
#include <iostream>
using std::cout;
class A { // 기본 클래스, 부모 클래스
private:
void a1() { cout << "a1\n"; }
void a2() { cout << "a2\n";}
public:
void b1() { cout << "b1\n"; }
void b2() { cout << "b2\n"; }
void b3() { cout << "b3\n"; }
void b4() { cout << "b4\n"; }
class B : public A { //파생 클래스, 자식 클래스
};
클래스 B는 클래스 A를 상속 받은 파생 클래스(or 자식 클래스)이다. 클래스 B는 클래스 A의 public만 상속받고 private은 상속받지 못한다.
부모 클래스
- 기본 클래스(Base Class), 슈퍼 클래스(Super Class)라고도 한다.
- 다른 클래스에 속성과 메서드를 '제공'하는 클래스이다.
- 자식 클래스가 상속받는 클래스임!
자식 클래스
- 파생 클래스(Derived Class), 서브 클래스(Sub Class)라고도 한다.
- 부모 클래스로부터 속성과 메서드를 '상속'받는 클래스이다.
- 상속받은 속성과 메서드를 그대로 사용할 수 있다.
- 상속받은 메서드를 오버라이딩(Overriding)하여 변경하거나 새로운 속성과 메서드를 추가할 수 있다.
- ★부모 클래스의 private은 상속받을 수 없다.
#include <iostream>
using std::cout;
using std::endl;
class A //기본 클래스
{
int x; //자동으로 private.
public:
void setX(int i) { x =i; }
void showX() { cout << x << endl; }
};
class B: public A //파생 클래스
{
//아무 것도 없음.
};
int main() {
A aa;
aa.setX(1);
aa.showX(); B bb;
bb.setX(10);
bb.showX();
return 0;
}
위의 코드에서 클래스 B는 클래스 A를 상속받았기 때문에 클래스 A의 public 속성과 메서드를 사용할 수 있다.
#include <iostream>
using std::cout;
using std::endl;
class A
{
int x;
public:
void setX(int i) { x = i; }
void showX() { cout << x << endl; }
};
class B :public A
{
int y;
public:
void setY(int i) { y = i; }
void showXY() { showX(); cout << y << endl; }
};
int main()
{
B bb;
bb.setX(1); // 기본클래스의 멤버접근
bb.setY(2); // 파생클래스의 멤버접근
bb.showX(); // 기본클래스의 멤버접근
bb.showXY(); // 파생클래스의 멤버접근
return 0;
}
상속받은 showX() 함수로 클래스 B에서 x를 출력할 수 있다.
private으로 상속을 받아도 기본 클래스의 private을 상속받는 것이 아니다!
private 상속은 기본 클래스의 protected와 public의 속성과 메서드를 '파생 클래스의 private'으로 상속받는 것이다.
이렇게 상속받은 private 멤버는 '파생 클래스와 기본 클래스만' 사용할 수 있다!
class A
{
int x; //int x=10; //가능?
public:
void setX(int i) { x = i; }
void showX() { cout << x << endl; }
};
class B :private A //비공개적으로 상속
{
int y;
public:
void setY(int i) { y = i; }
void showY() { cout << y << endl; }
};
상속받은 클래스 B의 상태는 ↓
class B:private A {
int y;
void setX(int i){x=i;}
void showX(){cout<<x<<endl;}
public:
void setY(int i){y=i;}
void showY(){ cout<<y<<endl;}
};
In-class member initializers
- 클래스 멤버 변수의 선언과 동시에 초기화를 하는 것이다.
#include <iostream>
using std::cout;
using std::endl;
class A
{
int x = 1 ;// In-class member initializers
public:
void setX(int i) { x = i; }
int getX() { return x ; }
};
int main()
{
A a1; //디폴트 생성자 호출, 눈에 안보이는 A(){}
cout << a1.getX()<<endl;
return 0;
}
private 상속 접근제어 예시
#include <iostream>
using std::cout;
using std::endl;
class A
{
int x;
public:
void setX(int i) { x = i; }
void showX() { cout << x << endl; }
};
class B :private A //비공개적으로 상속받는다
{
int y;
public:
void setXY(int i, int j) { setX(i); y = j; }
// 기본 클래스의 public 멤버 접근
void showXY() { showX(); cout << y << endl; }
};
int main()
{
B bb;
bb.setXY(1, 2); // 파생클래스의 멤버접근
bb.showXY(); // 파생클래스의 멤버접근
return 0;
}
Protected 상속
부모 클래스의 proteted 멤버와 public 멤버를 자식 클래스는 전부 자식 클래스 자신의 protected 멤버로만 받을 수 있다.
private 멤버 처럼 protected 멤버도 외부에서 접근할 수 없다.
Private과 Protected
- 공통점
- 외부에서 접근할 수 없다.
- 차이점
- private 멤버는 상속이 '불가능'하다.
- ★부모 클래스의 protected 멤버는 자식 클래스에게 상속할 수 있다.
단, 부모 클래스의 protected 멤버를 자식 클래스의 public 멤버로 상속받을 수는 없다.
Protected 상속 예시
#include <iostream>
using std::cout;
using std::endl;
class A
{
protected: //private이라면?
int a, b;
public:
void setAB(int i, int j) { a = i; b = j; }
};
class B :public A
{
int c; // private
public:
void setC(int n) { c = n; }
void showABC() { cout << a << b << c << endl; }
//기본 클래스의 protected 멤버들은
//파생 클래스의 멤버에 의해 접근될 수 있다.
};
int main()
{
A aa;
B bb;
bb.setAB(1, 2);
bb.setC(3);
bb.showABC();
return 0;
}
부모가 protected로 만든 후 자식이 public으로 상속받는 방식을 많이 쓴다.
상속에서 생성자와 소멸자
#include <iostream>
using std::cout;
class A
{
public:
A() { cout << "A의 생성자\n"; }
~A() { cout << "A의 소멸자\n"; }
};
class B :public A
{
public:
B() { cout << "B의 생성자\n"; }
~B() { cout << "B의 소멸자\n"; }
};
int main()
{
B ob;
return 0;
}
생성자는 부모 클래스가 먼저 실행되고 소멸자는 자식 클래스가 먼저 실행된다.
(생성자-부모 먼저, 소멸자-자식 먼저)
계층적 매개변수 전달
#include <iostream>
using std::cout;
using std::endl;
class A //할아버지
{
int a;
public:
A(int i) { a = i; }
int getA() { return a; }
};
class B :public A //아버지
{
int b;
public:
B(int i, int j) :A(i) {
// i는 기본 클래스 A의
//생성자 매개변수로 전달됨
b = j;
}
int getB() { return b; }
};
class C :public B //자식
{
int c;
public:
C(int i, int j, int k) :B(i, j) {
// i, j는 클래스 B의 생성자 매개변수로 전달됨
c = k;
}
void show() {
cout << getA() << ' ' << getB() << ' ' << c << endl;
}
};
int main()
{
C cc(10, 20, 30);
cc.show();
cout << cc.getA() << ' ' << cc.getB() << endl;
return 0;
}
반응형
'C++' 카테고리의 다른 글
C++ - overriding, 가상함수(virtual function) (0) | 2023.11.29 |
---|---|
C++ - 다중 상속 (0) | 2023.11.29 |
C++ - Overloading, Overriding (1) | 2023.11.18 |
C++ - Default Parameter (0) | 2023.11.15 |
C++ - 함수중첩(Function Overloading) (0) | 2023.11.15 |
Comments