본문 바로가기
C++

[C++ 프로그래밍] 12주차 상속(inheritance)

by heeaeeeee 2023. 11. 23.

1. 상속 코드1

aa라는 객체의 인스턴트가 접근할 때 public 에 있는 것들만 접근 가능

2. 상속 코드2

A라는 기본 클래스를 정의하고, B라는 클래스가 이를 상속받아 A의 public 메서드를 재사용할 수 있습니다. 그러나 private 메서드는 A 클래스 내에서만 접근 가능하므로 B 클래스에서는 사용할 수 없습니다.

3. 프로그래밍 언어에서 상속하는 문법

1. C++ : 콜론(:)과 함께 기본 클래스 이름을 명시하여 상속을 표현

class Base {
public:
    void baseFunction();
};

class Derived : public Base {
public:
    void derivedFunction();
};

2. Java : extends 키워드를 사용하여 상속을 표현

class Base {
    public void baseFunction() {}
}

class Derived extends Base {
    public void derivedFunction() {}
}

3. Python : 기본 클래스를 괄호 안에 넣어 상속을 표현

class Base:
    def baseFunction(self):
        pass

class Derived(Base):
    def derivedFunction(self):
        pass

4. JavaScript : extends 키워드를 사용하여 상속을 표현

class Base {
    baseFunction() {}
}

class Derived extends Base {
    derivedFunction() {}
}

5. C# : 콜론(:)과 함께 기본 클래스 이름을 명시하여 상속을 표현

class Base {
    public void BaseFunction() {}
}

class Derived : Base {
    public void DerivedFunction() {}
}

6. PHP : extends 키워드를 사용하여 상속을 표현

class Base {
    function baseFunction() {}
}

class Derived extends Base {
    function derivedFunction() {}
}

7. Ruby : 작은 부등호(<)를 사용하여 상속을 표현

class Base
    def base_function
    end
end

class Derived < Base
    def derived_function
    end
end

8. Swift :  콜론(:)을 이용해 상속을 표현

class Base {
    func baseFunction() {}
}

class Derived: Base {
    func derivedFunction() {}
}

9. Kotlin : 기본 클래스 앞에 open 키워드를 추가하고, 파생 클래스에서는 콜론(:)과 함께 기본 클래스를 명시하여 상속을 표현

open class Base {
    fun baseFunction() {}
}

class Derived: Base() {
    fun derivedFunction() {}
}

10. Scala : extends 키워드를 사용하여 상속을 표현

class Base {
    def baseFunction() {}
}

class Derived extends Base {
    def derivedFunction() {}
}

11. Go Go 언어 : 전통적인 클래스 기반 상속은 지원하지 않으며, 대신 임베딩을 통해 유사한 기능을 제공

type Base struct {
}

func (Base) baseFunction() {
}

type Derived struct {
    Base
}

func (Derived) derivedFunction() {
}

4. 클래스들의 계층구조

5. 상속 과정

6. 기본클래스와 파생클래스 : is-a, is_a, is a 관계

7. 클래스 상속 형식

8. public 상속 접근제어

private은 상속이 안되고 protected, public만 상속이 된다.

9. class Dog : public Animal

10. 상속 코드3

#include <iostream> 
// iostream 헤더 파일을 포함합니다. 이 헤더는 표준 입출력을 위한 라이브러리입니다.
using std::cout; 
// std 네임스페이스에서 cout을 사용하기 위한 선언입니다.
using std::endl; 
// std 네임스페이스에서 endl을 사용하기 위한 선언입니다.
class A // 'A'라는 이름의 기본 클래스를 정의합니다.
{
	int x; 
    // private 멤버 변수 x를 선언합니다. 기본적으로 클래스 내부의 멤버는 private입니다.
public: 
// 이후로 선언되는 멤버들은 public으로, 클래스 외부에서 접근 가능합니다.
	void setX(int i) { x = i;} 
    // 멤버 함수 setX를 선언하고 정의합니다. 이 함수는 인자로 받은 정수를 x에 저장합니다.
	void showX() { cout << x << endl; } 
    // 멤버 함수 showX를 선언하고 정의합니다. 이 함수는 x의 값을 출력합니다.
};
class B : public A // 'B'라는 이름의 클래스를 정의하고, public으로 'A'를 상속받습니다.
{ 
	// 클래스 'B'는 별도의 멤버가 없지만, 'A'의 public 멤버를 상속받습니다.
};
int main() { // 프로그램의 시작점인 main 함수를 정의합니다.
	A aa; 
    // 'A' 클래스의 객체 'aa'를 생성합니다.
	aa.setX(1); 
    // 'aa'의 멤버 함수 setX를 호출하여 'aa'의 멤버 변수 x에 1을 저장합니다.
	aa.showX();  
    // 'aa'의 멤버 함수 showX를 호출하여 'aa'의 멤버 변수 x의 값을 출력합니다.
	B bb; 
    // 'B' 클래스의 객체 'bb'를 생성합니다. 'B'는 'A'를 상속받았으므로 'A'의 public 멤버를 사용할 수 있습니다.
	bb.setX(10); 
    // 'bb'의 멤버 함수 setX를 호출하여 'bb'의 멤버 변수 x에 10을 저장합니다.
	bb.showX(); 
    // 'bb'의 멤버 함수 showX를 호출하여 'bb'의 멤버 변수 x의 값을 출력합니다.
	return 0; 
    // main 함수가 성공적으로 종료되었음을 시스템에 알립니다.
}

11. public 상속 접근제어로 상속 1

#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 showY() { cout << y << endl; }
};
int main()
{
	B bb; // 파생클래스의 객체
	bb.setX(1);
	bb.setY(2);
	bb.showX(); // 기본클래스의 멤버접근
	bb.showY(); // 파생클래스의 멤버접근
	return 0;
}

12. public 상속 접근제어로 상속 2

#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;
}

13.  private 상속 접근제어

14. class Dog : private Animal

private으로 상속하면 접근 속성 변경이 되어 private 쪽으로 들어온다.

15. private 상속 접근제어로 상속 1

#include <iostream>
using std::cout;
using std::endl;
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() { showX(); cout << y << endl; }
};
int main()
{
	A aa;
	B bb;
	aa.setX(1);
	aa.showX();
	bb.setY(2); // 파생클래스의 멤버접근
	bb.showY(); // 파생클래스의 멤버접근
	return 0;
}

16. In-class member initializers

//소스1
#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;
}

//소스2
#include <iostream>
using std::cout;
using std::endl;
class A
{
	int x = 1;
public:
	A() { x = 2; } //A() : x(2) {}
	void setX(int i) { x = i; }
	int getX() { return x; }
};
int main()
{
	A a1; //디폴트 생성자는 사라짐
	cout << a1.getX() << endl;
	return 0;
}

17. 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;
}

18. protected 상속 접근제어 속성

19. class Dog : protected Animal

20. 멤버접근제어속성

21. protected 접근제어속성

22. 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;
}

23. protected멤버+public상속

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; }
};

24. 상속에서 생성자와 소멸자

25. 상속에서 생성자와 소멸자

#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;
}

26. 매개변수가 있는 생성자를 갖는 클래스의 상속

27. 파생 클래스 생성자에서 기본 클래스 생성자에 매개변수전달 형식

파생클래스생성자(매개변수 리스트) :기본클래스생성자(매개변수리스트) { : }

#include <iostream>
using std::cout;
using std::endl;
class A {
	int a;
public:
	A(int i) {
		cout << "A의 생성자\n";
		a = i;
	}
	~A() { cout << "A의 소멸자\n"; }
	void showA() { cout << a << '\n'; }
};
class B :public A {
	int b;
public:
	B(int i, int j) :A(i) {// i는 기본클래스 생성자의 매개변수로 전달
		cout << "B의 생성자\n";
		b = j;
	}
	~B() { cout << "B의 소멸자\n"; }
	void showB() { cout << b << endl; }
};
int main()
{
	B bb(10, 20);
	bb.showA();
	bb.showB();
	return 0;
}

28. 계층적 다중상속에서계층적 매개변수전달 1

#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;
}

29. 계층적 다중상속에서 계층적 매개변수 전달 2

#include <iostream>
using std::cout;
using std::endl;
class B { //할아버지
	double d;
public:
	B(double dd) { d = dd; }
	double getD() { return d; }
};
class D1 :public B { //아버지
	int i;
public:
	D1(double dd, int ii) :B(dd) { i = ii; }
	int getI() { return i; }
};
class D2 :public D1 { //자식
	char c;
public:
	D2(double dd, int ii, char cc) :D1(dd, ii) { c = cc; }
	void print() {
		cout << "Double : " << getD() << endl;
		// B 멤버 호출
		cout << "Int : " << getI() << endl;
		// D1 멤버 호출
		cout << "Char : " << c << endl;
	}
};
int main()
{
	D2 d2(10.5, 10, 'H');
	cout << d2.getD() << ',' << d2.getI() << endl;
	// B, D1 멤버 호출
	d2.print();
	ret

 

 

C++ 강의 자료 참고했습니다.