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

  • 하나의 클래스는 다른 클래스 멤버를 포함할 수 있다

좋은 웹페이지 즐겨찾기