2024년 2학기/C++ 프로그래밍

2학기 12주차 과제

윤지선 2024. 11. 18. 15:40

객체지향 언어의 세가지 특징 : 캡슐화, 상속, 다형성

 

 

a1 a2 함수는 캡슐화 때문에 private 속성이라서 클래스 밖에서 접근되지 않음.

 

부모가 있고 상속받으면 모든것을 물려받는것이 아닌 public부분만 물려받음.

 

protected라고 되어있어도 접근이 안된다(?)

 

#include <iostream>
using std::cout;

// 클래스 A 정의: 기본 클래스 또는 부모 클래스
class A 
{
private:
    // private 멤버 함수들: 클래스 내부에서만 접근 가능
    void a1() {cout << "a1\n";}
    void a2() {cout << "a2\n";}

protected:
    // protected 멤버 함수들: 이 클래스와 파생 클래스에서 접근 가능
    void p1() { cout << "p1\n"; }
    void p2() { cout << "p2\n"; }

public:
    // public 멤버 함수들: 어디서든 접근 가능
    void b1() {cout << "b1\n"; }
    void b2() {cout << "b2\n"; }
    void b3() {cout << "b3\n"; }
    void b4() {cout << "b4\n";}
};

// 클래스 B 정의: A 클래스로부터 public으로 상속받음
class B : public A {
    // B 클래스는 A의 public과 protected 멤버들을 상속받음
}; 

int main() {
    A aa; // A 클래스의 객체 생성
    //aa. // aa 객체는 A 클래스의 public 멤버만 접근 가능

    B bb; // B 클래스의 객체 생성
    //bb. // bb 객체는 A 클래스에서 상속받은 public 멤버와 B 클래스의 public 멤버에 접근 가능

    return 0;
}

 

 

JAVA

class Animal {
    void makeSound() {
        System.out.println("The animal makes a sound");
    }
}

class Dog extends Animal {
    void makeSound() {
        System.out.println("The dog barks");
    }
}

 

 

자바스크립트

class Animal {
    makeSound() {
        console.log("The animal makes a sound");
    }
}

class Dog extends Animal {
    makeSound() {
        console.log("The dog barks");
    }
}

 

 

C#

class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("The animal makes a sound");
    }
}

class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("The dog barks");
    }
}

 

 

C++

class Animal {
public:
    virtual void makeSound() {
        std::cout << "The animal makes a sound" << std::endl;
    }
};

class Dog : public Animal {
public:
    void makeSound() override {
        std::cout << "The dog barks" << std::endl;
    }
};

 

 

 

 

기말에 클래스다이어그램 그리는 문제 나옴!

상속을 표현할 때는 is a 관계라고 한다

 

객체지향언어에서 부모와 자식 클래스의 용어

 

class Dog : public Animal{

};

Dog : 파생클래스명

public : 상속접근제어

Animal : 기본클래스명

=> Animal 클래스로부터 public으로 상속받은 Dog 클래스

# 상속접근제어로 튜닝을 한다!

 

public를 제일 많이 사용함

# 부모의 private는 절대 상속되지 않음.

# public로 상속이 되었을 때는 부모의 속성을 그대로 물려받음.

 

위의 표 분석
private는 상속되지 않음.
private이기 때문에 상속받지 못해서 오류발생.

 

오류발생
상속이 되긴 되지만 private로 넘어감.

 

# 기본적으로 자식만 접근할 수 있도록 함.

 

private으로 상속하는 경우

 

쓰레기값

 

결과 : 2
생성자를 이렇게 쓸 수도 있음
protected 상속
C++에서 protected로 상속하는 경우

 

 

 

# protected도 외부에서 바로 접근 불가능.

 

# protected가 상속까지 고려했을 때에는 더 좋음. 

 

위 두 소스의 차이점
공통점

#include <iostream>
using std::cout;
using std::endl;

class A
{
protected: // A 클래스와 그 파생 클래스에서만 접근 가능
    // private이라면 A 클래스 내부에서만 접근 가능하며, 파생 클래스에서도 직접 접근 불가
    int a, b;
public:
    // a와 b 값을 설정하는 public 메서드
    void setAB(int i, int j) { a = i; b = j; }
};

class B : public A // B 클래스는 A 클래스를 public으로 상속
{
    int c; // private 멤버 변수, B 클래스 내부에서만 접근 가능
public:
    // c 값을 설정하는 public 메서드
    void setC(int n) { c = n; }
    
    // a, b, c 값을 출력하는 public 메서드
    void showABC() { cout << a << b << c << endl; }
    // a와 b는 A 클래스의 protected 멤버이므로 B 클래스에서 접근 가능
    // A의 멤버가 private이었다면 이 부분에서 컴파일 에러 발생
};

int main()
{
    A aa; // A 클래스의 객체 생성
    B bb; // B 클래스의 객체 생성

    //aa.a; // 오류: a는 protected(또는 private)이므로 외부에서 직접 접근 불가
    //bb.b; // 오류: b도 마찬가지로 외부에서 직접 접근 불가

    bb.setAB(1, 2); // B 객체를 통해 A의 public 메서드 호출
    bb.setC(3);     // B의 public 메서드 호출
    bb.showABC();   // 1, 2, 3 출력

    return 0;
}

 

 

 

 

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

실행결과
:A() 의 의미

 

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

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

 

# 다중상속은 문제점이 많아서 크게 잘 쓰지는 않음. 

다중상속의 문제점

 

 

#include <iostream>
using std::cout;
class A1 // 기본 클래스 1
{
	int a;
public:
	A1() { cout << "A1의 생성자.\n"; }
	~A1() { cout << "A1의 소멸자.\n"; }
};
class A2 // 기본 클래스 2
{
	int b;
public:
	A2() { cout << "A2의 생성자.\n"; }
	~A2() { cout << "A2의 소멸자.\n"; }
};
class B : public A1, public A2
	// 기본 클래스 1과 2로부터
	// 상속 받은 파생 클래스
{
	int c;
public:
	B() { cout << "B의 생성자.\n"; }
	~B() { cout << "B의 소멸자.\n"; }
};
int main()
{
	B bb;
	return 0;
}

실행결과

 

#include <iostream>
using std::cout;
class A2 // 기본 클래스 1
{
	int a;
public:
	A2() { cout << "A1의 생성자.\n"; }
	~A2() { cout << "A1의 소멸자.\n"; }
};
class A1 // 기본 클래스 2
{
	int b;
public:
	A1() { cout << "A2의 생성자.\n"; }
	~A1() { cout << "A2의 소멸자.\n"; }
};
class B : public A1, public A2
	// 기본 클래스 1과 2로부터
	// 상속 받은 파생 클래스
{
	int c;
public:
	B() { cout << "B의 생성자.\n"; }
	~B() { cout << "B의 소멸자.\n"; }
};
int main()
{
	B bb;
	return 0;
}

실행결과

#include <iostream>
using std::cout;
using std::endl;
using std::string;
// 사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
// 멤버변수를 초기화하는 생성자를 구현하시오.
// 기타 함수를 구현하시오.

class Man {
protected:
	int age;
	string name;
public:
	Man(string n, int a) {
		name = n;
		age = a;
	}
	void m_show() {
		cout << "이름 :" << name << endl;
		cout << "나이 :" << age << endl;
	}

};

int main()
{
	/*Student kks("김컴소", 20, "C반", "202012000");
	Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
	kks.s_show();
	hsh.t_show();*/
	return 0;
}

부모클래스 구현

 

#include <iostream>
using std::cout;
using std::endl;
using std::string;
// 사람클래스(Man, 멤버변수:이름, 나이)를 만드시오.
// 멤버변수를 초기화하는 생성자를 구현하시오.
// 기타 함수를 구현하시오.

class Man {
protected:
	int age;
	string name;
public:
	Man(string n, int a) {
		name = n;
		age = a;
	}
	void m_show() {
		cout << "이름 :" << name << endl;
		cout << "나이 :" << age << endl;
	}

};
//사람클래스로부터 상속받은 학생클래스(Student)를 만드시오.
//(멤버변수:반, 학번), 생성자, 기타함수
class Student : public Man {
	string ban;
	string hak;
public:
	Student(string n, int a, string b, string h) : Man(n,a) {
		ban = b;
		hak = h;
	}
	void s_show() {
		m_show();
		cout << "반 :" << ban << endl;
		cout << "학번 :" << hak << endl;
	}
};
int main()
{
	Student kks("김컴소", 20, "C반", "202012000");
	//Teacher hsh("한미소", 40, "전산", "C++프로그래밍");
	kks.s_show();
	//hsh.t_show();
	return 0;
}

 

실행결과