2학년 객체지향프로그래밍 06주차수업
상속
-
Inheritance
- OOP에서 재사용을 확보하는 방법
- 아이디어 : 클래스의 일부 또는 모든 특성은 다른 클래스에서 파생될 수 있다
- 파생 클래스를 서브 클래스라고 하며, 기존 클래스를 base클래스 or 슈퍼 클래스라고 합니다.
-
Three modes : Public, Protected, and Private
- Public : 누구나 접근 가능
- Protected : 기본 멤버 함수와 파생 클래스 모두에서 접근 가능
- Private : 기본 멤버 함수만 접근 가능 (파생 클래스 X)
-
정의 : class derived-class-name : visibility-mode base-classname
class B {
int a;
public:
int b;
void get_ab();
int get_a(void);
void show_a(void);
};
void B::get_ab() {
a = 5, b = 10;
}
int B::get_a() {
return a;
}
void B::show_a() {
cout << "a = " << a << endl;
}
class D : public B {
int c;
public:
void mul(void);
void display(void);
};
void D::mul() {
c = b * get_a();
}
void D::display() {
cout << "a = " << get_a() << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
int main() {
D d;
d.get_ab();
d.mul();
d.show_a();
d.display();
d.b = 20;
d.mul();
d.display();
return 0;
}
- B의 모든 public 멤버는 public으로 D에게 상속됩니다.
- D 또한 B의 모든 public 멤버 함수에 접근할 수 있습니다.
- B에서 a는 private이지만 D의 객체는 상속받은 public함수를 통해 접근할 수 있습니다.
class D : private B {
int c;
public:
void mul(void);
void display(void);
};
void D::mul() {
c = b * get_a();
}
void D::display() {
cout << "a = " << get_a() << endl;
cout << "b = " << b << endl;
cout << "c = " << c << endl;
}
int main() {
D d;
d.get_ab();//error
d.mul();
d.show_a();//error
d.display();
d.b = 20;//error
d.mul();
d.display();
return 0;
}
- 클래스 B의 모든 public 멤버는 d에게 private형태로 상속된다.
- 클래스 B의 private멤버에 직접 접근 할 수 없다.
- mul()함수에서 get_ab()함수를 호출할수 있다
다중상속
- 하나의 클래스는 한개 이상의 클래스를 상속할수 있다
- Syntax : 컴마로 구분
- Class D : visibility B-1, visibility B-2
class M {
protected:
int m;
public:
void get_m(int);
};
class N {
protected:
int n;
public:
void get_n(int);
};
class P : public M, public N {
public:
void display(void);
};
void M::get_m(int x) { m = x; }
void N::get_n(int x) { n = x; }
void P::display() {
cout << "m = " << m << endl;
cout << "n = " << n << endl;
cout << "m*n = " << m * n << endl;
}
int main() {
P p;
p.get_m(10);
p.get_n(20);
p.display();
return 0;
}
- 예시 : 클래스 P는 클래스 M 과 N의 자식클래스이다
class M {
public:
void display() {
cout << "M" << endl;
}
};
class N {
public:
void display() {
cout << "N" << endl;
}
};
class P : public M, public N {
public:
void display(void) { M::display(); }
};
int main() {
P p;
p.display();
return 0;
}
- 모호성 해결
- 같은 이름의 함수가 2개 이상의 클래스에 나타나는 경우 연산자 ::로 분별 가능
class A {
public:
void display() {
cout << "A" << endl;
}
};
class B : public A {
public:
void display() {
cout << "B" << endl;
}
};
int main() {
B b;
b.display(); // B
b.A::display(); // A
b.B::display(); // B
return 0;
}
- 오버라이딩 : 파생함수는 상속된 함수를 재정의 할 수 있습니다
가상 기본 클래스
class student {
protected:
int roll_number;
public:
void set_number(int a) {
roll_number = a;
}
void print_number() {
cout << "Roll No: "
<< roll_number << endl;
}
};
class test :virtual public student {
protected:
float part1, part2;
public:
void set_marks(float x, float y) {
part1 = x; part2 = y;
}
void print_marks() {
cout << "part1 = " << part1
<< endl << "part2 = "
<< part2 << endl;
}
};
class sports :virtual public student {
protected:
float score;
public:
void set_score(float s) {
score = s;
}
void print_score() {
cout << "score = " << score
<< endl;
}
};
class result : public test, public sports {
float total;
public:
void display();
};
void result::display() {
total = part1 + part2 + score;
print_number();
print_marks();
print_score();
cout << "total score = " << total<< endl;
}
int main() {
result student_a;
student_a.set_number(500);
student_a.set_marks(30., 50.);
student_a.set_score(100);
student_a.display();
return 0;
}
- 다중 상속의 경우 한 클래스를 2번 상속받을 경우 멤버가 중복되어 메모리가 낭비되고 멤버의 모호함이 발생
- 클래스를 2번 상속받아도 한번만 상속하도록 해주는 가상 기반 클래스를 사용함
Abstract class
class animal {
public:
virtual void cry() = 0;
};
class dog :public animal {
public:
void cry() { cout << "Wal!" << endl; }
};
class cat :public animal {
public:
void cry() { cout << "Nyaoooon!" << endl; }
};
- 추상 클래스
- 한개 이상 순수 가상함수를 갖는 클래스
- 객체를 만들 수 없다
가상함수
-
두 가지 유형의 가상 함수
-
가상 함수(Virtual function) : 파생 클래스에 의해 재정의 될 수 있습니다.
- 함수 선언의 시작부분에 virtual키워드 작성
-
순수 가상 함수(Pure Virtual function) : 파생 클래스에서 재정의해야 한다.
- 선언시 0을 할당 -> virtual void func() = 0;
- 클래스에서 순수 가상함수가 있는 경우 이를 추상 클래스라고 한다
-
-둘다 런타임의 다형성 기능입니다.
파생클래스의 생성자
- 기본클래스에 하나 이상의 인수가 있는 생성자가 포함된 경우 파생 클래스에 생성자를 제공해야 한다
- 생성자 실행됨
- 다중 상속에서 파생 클래스의 선언에서 기본 클래스가 나타나는 순서대로 생성자 실행
- 다단계 상속에서 상속 순서대로 생성자 실행
class alpha {
int x;
public:
alpha(int i) {
x = i;
cout << "alpha init" << endl;
}
};
class beta {
float y;
public:
beta(float j) {
y = j;
cout << "beta init" << endl;
}
};
class gamma : public beta, public alpha {
int m, n;
public:
gamma(int a, float b, int c, int d) :
alpha(a), beta(b)
{
//initialization for gamma
m = c;
n = d;
cout << "gamma init" << endl;
}
};
int main() {
gamma g(5, 10.0, 20, 30);
return 0;
}
- 순서 : beta -> alpha -> gamma
Nesting of Classes
-
하나의 클래스는 다른 클래스 멤버를 포함할 수 있다
Author And Source
이 문제에 관하여(2학년 객체지향프로그래밍 06주차수업), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@sgh9702/2학년-객체지향프로그래밍-06주차수업-js9pyjgw저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)