• 검색 결과가 없습니다.

이번장에서만들어볼프로그램

N/A
N/A
Protected

Academic year: 2021

Share "이번장에서만들어볼프로그램"

Copied!
59
0
0

로드 중.... (전체 텍스트 보기)

전체 글

(1)

11 장 상속 제 11 장 상속

1. 상속 개념

2. 상속시 생성자와 소멸자 호출 순서

3. 부모클래스 생성자 호출

4. 상속과 접근 지정자

5. 상속시 접근 지정

6. 다중 상속

(2)

이번 장에서 만들어 볼 프로그 램

class Circle { int x, y;

int radius;

...

}

class Rect { int x, y;

int width, height;

...

}

중복

(3)

상속의 개요

(4)

C++ 에서의 상속 (Inheritance)

C++ 에서의 상속이란 ?

클래스 사이에서 상속관계 정의

기본 클래스의 속성과 기능을 파생 클래스에 물려주는 것

기본 클래스 (base class) - 상속해주는 클래스 . 부모 클래스

파생 클래스 (derived class) – 상속받는 클래스 . 자식 클래스

기본 클래스의 속성과 기능을 물려받고 자신 만의 속성과 기능을 추 가하여 작성

기본 클래스에서 파생 클래스로 갈수록 클래스의 개념이 구체화

다중 상속을 통한 클래스의 재활용성 높임

4

(5)

상속의 정의

상속 접근 지정자

(6)

상속의 표현

6

(7)

상속의 목적 및 장점

1. 간결한 클래스 작성

기본 클래스의 기능을 물려받아 파생 클래스를 간결하게 작성

2. 클래스 간의 계층적 분류 및 관리의 용이함

상속은 클래스들의 구조적 관계 파악 용이

3. 클래스 재사용과 확장을 통한

소프트웨어 생산성 향상

빠른 소프트웨어 생산 필요

기존에 작성한 클래스의 재사용 상속

상속받아 새로운 기능을 확장

앞으로 있을 상속에 대비한 클래스의 객체 지향적 설계 필요

7

(8)

예제

8

// 한 점을 표현하는 클래스 Point 선언 class Point {

int x, y; //(x,y) 좌표값 public:

void set(int x, int y)

{ this->x = x; this->y = y; } void showPoint() {

cout << "(" << x << "," << y << ")"

<< endl;

} };

class ColorPoint : public Point { string color;// 점의 색 표현

public:

void setColor(string color) { this->color = color; }

void showColorPoint();

};

void ColorPoint::showColorPoint() { cout << color << ":";

showPoint();

}

int main() { Point p;

ColorPoint cp;

cp.set(3,4);

cp.setColor("Red");

cp.showColorPoint();

}

(9)

자식클래스와 부모클래스

(10)

자식 클래스의 객체 구성

10

int x

Point p;

void set() {...}

int y

void showPoint() {...}

ColorPoint cp;

void set() {...}

void showPoint() {...}

string color

void showColorPoint() { ... }

void setColor () {...}

int x int y

자식클래스의 객체는 기본 클래스의 멤버 포함

기본클래스 멤버

자식클래스 멤버 class Point {

int x, y;

public:

void set(int x, int y);

void showPoint();

};

class ColorPoint : public Point { string color;

public:

void setColor(string color);

void showColorPoint();

};

(11)

자식 클래스에서 기본 클래스 멤버 접근

11 ColorPoint cp 객체

void set(int x, int y) { this->x= x; this-

>y=y;

}void showPoint() { cout << x << y;

}

color

void showColorPoint() { cout << color <<

":";

showPoint();

}

void setColor ( ) { ... } x

y

Point 멤버

ColorPoint 멤버 자식클래스에서 기본

클래스 멤버 호출

(12)

외부에서 자식 클래스 객체에 대한 접근

12

ColorPoint cp;

cp.set(3, 4);

cp.setColor("Red");

cp.showColorPoint();

main()

ColorPoint cp 객체 void set(int x, int y) {

this->x= x; this-

>y=y;

}void showPoint() { cout << x << y;

}

color “Red”

void showColorPoint() {

cout << color <<

":";

showPoint();

}

void setColor (string color) {

this->color = color;

}

x 3

y 4

(13)

예제

class Car {

int speed;

};

class SportsCar : public Car {

bool turbo;

};

(14)

예제

(15)

class Car {

예제

int speed; // 속도

public:

void setSpeed(int s) { speed = s;

}

int getSpeed() { return speed;

} };

// Car 클래스를 상속받아서 다음과 같이 SportsCar 클래스를 작성한다 . class SportsCar : public Car {

bool turbo;

public:

void setTurbo(bool newValue) { turbo = newValue;

}

bool getTurbo() { return turbo;

} };

int main() {

SportsCar c;

c.setSpeed(60);

c.setTurbo(true);

c.setSpeed(100);

c.setTurbo(false);

return 0;

}

(16)

상속은 왜 필요한가 ?

상속

(17)

상속 계층도

·

상속은 여러 단계로 이루어질 수 있다 .

(18)

상속 계층도

(19)

상속은 is-a 관계

상속은 is-a 관계

자동차는 탈것이다 . ( Car is a Vehicle).

사자 , 개 , 고양이는 동물이다 .

has-a( 포함 ) 관계는 상속으로 모델링을 하면 안 된다 .

도서관은 책을 가지고 있다 ( Library has a book).

거실은 소파를 가지고 있다 .

(20)

상속 예제

(21)

Lab: 도형과 사각형

(22)

class Shape {

예제

int x, y;

public:

void setX(int xval) { x = xval; } void setY(int yval) { y = yval; } };

class Rectangle : public Shape { int width, height;

public:

void setWidth(int w) { width = w; } void setHeight(int h) { height = h; }

int getArea() { return (width * height); } };

int main() { Rectangle r;

r.setWidth(5);

r.setHeight(6);

cout << " 사각형의 면적 : " << r.getArea()

<< endl;

return 0;

}

(23)

상속 관계의 생성자와 소멸자 실행

자식 클래스의 객체가 생성될 때 자식 클래스의 생성자 와 기본 클래스의 생성자가 모두 실행되는가 ? 아니면 자식 클래스의 생성자만 실행되는가 ?

자식 클래스의 생성자와 기본 클래스의 생성자 중에서 어떤 생성자가 먼저 실행되는가 ?

객체가 소멸될 경우에 그 순서는 ?

23

(24)

상속에서의 생성자와 소멸자

부모 클래스의 생성자가 먼저 실행된 후에 자식 클래스 의 생성자가 실행

자식 클래스의 소멸자가 먼저 실행되고 , 부모 클래스의 소멸자가 나중에 실행

(25)

생성자 호출 관계 및 실행 순서

25

class A { public:

A() { cout << " 생성자 A"

<< endl; }

~A() { cout << " 소멸자 A"

<< endl; } };

class B : public A { public:

B() { cout << "생성자 B"

<< endl; }

~B() { cout << "소멸자 B"

<< endl; } };

class C : public B { public:

C() { cout << " 생성자 C"

<< endl; }

~C() { cout << "소멸자 C"<< endl; }

};

int main() { C c;

return 0;

}

A() 실행 

B() 실행 

C() 실행  C() 호출 

B() 호출  A() 호출 

리턴

리턴

생성자 A 생성자 B 생성자 C 소멸자 C 소멸자 B 소멸자 A

컴파일러는 C() 생성자 실행 코 드를 만들때 , 생성자 B() 를 호 출하는 코드 삽입

(26)

class Shape {

예제

int x, y;

public:

Shape() { cout << "Shape 생성자 () " << endl; }

~Shape() { cout << "Shape 소멸자 () " << endl; } };

class Rectangle : public Shape { int width, height;

public:

Rectangle() { cout << "Rectangle 생성자 ()" << endl; }

~Rectangle() { cout << "Rectangle 소멸자 ()" << endl; } };

int main() {

Rectangle r;

return 0;

}

실행 결과

는 ?

(27)

부모 클래스 생성자 호출

부모 클래스의 생성자를 명시하지 않으면 , 항상 기본 생 성자가 호출

다른 부모 생성자를 호출하려면 해당 부모 생성자를 다 음과 같이 명시

(28)

class A { public:

A() { cout << "생성자 A" << endl; } A(int x) {

cout << "매개변수생성자 A" << x

<< endl;

} };

부모클래스 생성자가 명시되지 않으면 ?

28

컴파일러는 기본 생성자를 호출

class B : public A { public:

B() { // A() 호출하도록 컴파일

cout << " 생성자 B" <<

endl;

} };

int main() { B b;

}

생성자 A 생성자 B

(29)

class A { public:

A(int x) {

cout << "매개변수생성자 A" << x

<< endl;

} };

부모클래스에 기본 생성자가 없으면 ?

29

class B : public A { public:

B() { // A() 호출하도록 컴파일

cout << " 생성자 B" <<

endl;

} };

int main() { B b;

}

(30)

자식클래스 생성자가 매개 변수를 갖는 경우는 ?

30

부모클래스의 기본 생성자 호출

class A { public:

A() { cout << " 생성자 A" << endl; } A(int x) {

cout << "매개변수생성자 A" << x

<< endl;

} };

class B : public A { public:

B() { // A() 호출하도록 컴파일됨 cout << " 생성자 B" << endl;

}B(int x) { // A() 호출하도록 컴파일됨 cout << " 매개변수생성자 B" << x <<

endl;

}; } int main() {

B b(5);

}

(31)

자식 클래스 생성자에서 부모 클래스의 생성자 선택

31

class A { public:

A() { cout << " 생성자 A" << endl; } A(int x) {

cout << " 매개변수생성자 A" << x

<< endl;

} };

class B : public A { public:

B() { // A() 호출하도록 컴파일됨

cout << " 생성자 B" << endl;

}

B(int x) : A(x+3) {

cout << " 매개변수생성자 B" << x

<< endl;

} };

int main() { B b(5);

}

(32)

컴파일러의 기본 생성자 호출 코드 삽입

32

class B {

B() : A() {

cout << " 생성자 B" << endll;

}

B(int x) : A() {

cout << " 매개변수생성자 B" << x

<< endll;

} };

컴파일러가 묵시적으로 삽입한 코드

(33)

부모 클래스 생성자 호출

부모 클래스 생성자 호출 다음에 멤버 초기화 리스트를 작성할 수 있음

Rectangle(int x=0, int y=0, int w=0, int h=0) : Shape(x, y) {

width = w;

height = h;

}

Rectangle(int x=0, int y=0, int w=0, int h=0) : Shape(x, y), width(w), height(h)

{ }

(34)

예제

class Shape { int x, y;

public:

Shape() {

cout << "Shape 생성자 () " << endl;

}

Shape(int xloc, int yloc) : x{xloc}, y{yloc} {

cout << "Shape 생성자 (xloc, yloc) " << endl;

}

~Shape() {

cout << "Shape 소멸자 () " << endl;

} };

class Rectangle : public Shape { int width, height;

public:

Rectangle::Rectangle(int x, int y, int w, int h) : Shape(x, y) { width = w;

height = h;

cout << "Rectangle 생성자 (x, y, w, h)" << endl;

}

~Rectangle() {

cout << "Rectangle 소멸자 ()" << endl;

} };

(35)

예제

class Shape { int x, y;

public:

Shape() {

cout << "Shape 생성자 () " << endl;

}

Shape(int xloc, int yloc) : x{xloc}, y{yloc} {

cout << "Shape 생성자 (xloc, yloc) " << endl;

}

~Shape() {

cout << "Shape 소멸자 () " << endl;

} };

class Rectangle : public Shape { int width, height;

public:

Rectangle::Rectangle(int x, int y, int w, int h) : Shape(x, y) { width = w;

height = h;

cout << "Rectangle 생성자 (x, y, w, h)" << endl;

}

~Rectangle() {

cout << "Rectangle 소멸자 ()" << endl;

} };

int main() {

Rectangle r(0, 0, 100, 100);

return 0;

}

실행 결과

는 ?

(36)

Lab: 컬러 사각형

사각형을 Rect 클래스로 나타내자 . 이 클래스를 상속 받아서 컬러 사각형 ColoredRect 을 정의해보자 . Col- oredRect 클래스를 이용하여 화면에 다음과 같은 색깔 있는 사각형을 그려보자 .

(37)

class Rect {

예제

protected:

int x, y, width, height;

public:

Rect(int x, int y, int w, int h) : x(x), y(y), width(h), height(h) { } void draw()

{

HDC hdc = GetWindowDC(GetForegroundWindow());

Rectangle(hdc, x, y, x + width, y + height);

} };

class ColoredRect : Rect { int red, green, blue;

public:

ColoredRect(int x, int y, int w, int h, int r, int g, int b) : Rect(x, y, h, w), red(r), green(g), blue(b) { }

void draw() {

HDC hdc = GetWindowDC(GetForegroundWindow());

SelectObject(hdc, GetStockObject(DC_BRUSH));

SetDCBrushColor(hdc, RGB(red, green, blue));

Rectangle(hdc, x, y, x + width, y + height);

} };

(38)

예제

int main() {

Rect r1(100, 100, 80, 80);

ColoredRect r2(200, 200, 80, 80, 255, 0, 0);

r1.draw();

r2.draw();

return 0;

}

(39)

접근 지정자

(40)

protected 접근 지정

접근 지정자

private 멤버

선언된 클래스 내에서만 접근 가능

자식 클래스에서도 기본 클래스의 private 멤버 직접 접근 불가

Public 멤버

선언된 클래스나 외부 어떤 클래스 , 모든 외부 함수에 접근 허용

자식 클래스에서 기본 클래스의 public 멤버 접근 가능

Protected 멤버

선언된 클래스에서 접근 가능

자식 클래스에서만 접근 허용

자식 클래스가 아닌 다른 클래스나 외부 함수에서는 protected 멤버 를 접근할 수 없다 .

40

(41)

접근 지정자

(42)

멤버의 접근 지정에 따른 접근

42

class A { private:

private

protected:

protected 멤버

public:

public 멤버 };

class B : public A {

};

class C {

};

void function() {

}

외부 함수 기본 클래스 다른 클래스

자식 클래스

(43)

class Person {

예제

string name;

protected:

string address;

};

class Student : public Person { public:

void setAddress(string add) { address = add;

}

string getAddress() { return address;

} };

int main() {

Student obj;

obj.setAddress(" 서울시 종로구 1 번지 ");

cout << obj.getAddress() << endl;

return 0;

}

(44)

멤버 함수 재정의

자식 클래스가 필요에 따라 상속된 멤버 함수를 재정의 하여 사용하는 것을 의미한다 .

함수 재정의를 오버라이딩 (overriding) 이라 함

(45)

예제

#include <iostream>

#include <string>

using namespace std;

class Animal { public:

void speak() {

cout << " 동물이 소리를 내고 있음 " << endl;

} };

class Dog : public Animal { public:

void speak() {

cout << " 멍멍 !" << endl;

} };

int main() {

Dog obj;

obj.speak();

return 0;

}

(46)

함수의 중복 정의와 재정의

(47)

부모 클래스의 멤버 함수 호출

상속에서 부모 클래스의 멤버 함수를 호출하려면 ::’ ‘ 을 사용하여 부모클래스를 명시하면 됨

ParentClass::print()

보통 , 자식클래스의 멤버 함수는 부모 클래스 버전을 먼 저 ( 혹은 나중에 ) 호출하여 일정 작업을 한 후에 자신의 역할을 수행하는 방식으로 작성됨

(48)

예제

#include <iostream>

#include <string>

using namespace std;

class ParentClass { public:

void print() {

cout << " 부모 클래스의 print() 멤버 함수 " << endl;

} };

class ChildClass : public ParentClass { int data;

public:

void print() { // 멤버 함수 재정의 ParentClass::print();

cout << " 자식 클래스의 print() 멤버 함수 " << endl;

} };

(49)

부모 클래스를 상속받는 3 가지 방법

(50)

상속시 접근 지정

상속 선언 시 public, private, protected 의 3 가지 중 하 나 지정

기본 클래스의 멤버의 접근 속성을 어떻게 계승할지 지 정

public – 기본 클래스의 protected, public 멤버 속성을 그대로 계

private – 기본 클래스의 protected, public 멤버를 private 으로 계승

protected – 기본 클래스의 protected, public 멤버를 protected 로 계승

상속 접근지정자 생략시에는 private 상속으로 처리됨 에 유의할 것

50

(51)

상속 시 접근 지정에 따른 멤버의 접근 지정 속 성 변화

51 class Base { private:

int a;

protected:

int b;

public:

int c;

};

class Derived : public Base {

.... // Derived 멤버 };

protected:

int b;

public:

int c;

.... // Derived 멤

class Derived : protected Base { .... // Derived 멤버

};

class Derived : private Base {

.... // Derived 멤버 };

protected:

int b;

int c;

.... // Derived 멤

private:

int b;

int c;

.... // Derived 멤

상속 후 Derived

class Base { private:

int a;

protected:

int b;

public:

int c;

};

class Base { private:

int a;

protected:

int b;

public:

int c;

};

상속 후 Derived

상속 후 Derived

public 상속

protected 상속

private 상속

Base 영역

Base 영역

Base 영역 Derived 영역

Derived 영역

Derived 영역

(52)

에제

#include <iostream>

using namespace std;

class Base {

public: int x;

protected: int y;

private: int z;

};

class Derived : private Base{

// x 는 자식 클래스에서 사용가능하지만 private 로 지정된다 . // y 는 자식 클래스에서 사용가능하지만 private 로 지정된다 . // z 는 자식 클래스에서도 사용할 수 없다 .

};

int main() {

Derived obj;

cout << obj.x;

}

(53)

Lab: 게임에서의 상속 모델링

Alien, Player 는 미사일 , 경기자를 표현

이들은 화면에서 움직이는 작은 그림인 sprite 의 공통부 분을 가짐

(54)

에제

class Sprite { int x, y;

string image;

public:

Sprite(int x, int y, string image) : x(x), y(y), image(image) { } void draw() { }

void move() { } };

class Alien : public Sprite { int speed;

public:

Alien(int x, int y, string image) : Sprite(x, y, image) { } void move() { }

};

class Player : public Sprite { string name;

public:

Player(int x, int y, string image) : Sprite(x, y, image) { } void move() { }

};

int main() {

Alien a( 0, 100,

"image1.jpg" );

Player p(0, 100,

"image1.jpg");

return 0;

}

(55)

다중 상속

다중 상속 (multiple inheritance) 이란 하나의 자식 클래스 가 두개 이상의 부모 클래스로부터 멤버를 상속받는 것 을 의미한다 .

(56)

에제

class PassangerCar { public:

int seats; // 정원

void set_seats(int n) { seats = n; } };

class Truck { public:

int payload; // 적재 하중

void set_payload(int load) { payload = load; } };

class Pickup : public PassangerCar, public Truck { public:

int tow_capability; // 견인 능력

void set_tow(int capa) { tow_capability = capa; } };

int main() {

Pickup my_car;

my_car.set_seats(4);

my_car.set_payload(10000 );

my_car.set_tow(30000);

return 0;

}

(57)

예제 : Adder 와 Subtractor 를 다중 상속받는 Calculator 작성

57

class Adder { protected:

int add(int a, int b) { return a+b; }

};

class Subtractor { protected:

int minus(int a, int b) { return a-b; }

};

int main() {

Calculator handCalculator;

cout << "2 + 4 = "

<< handCalculator.calc('+', 2, 4) << endl;

cout << "100 - 8 = "

<< handCalculator.calc('-', 100, 8) << endl;

}

// 다중 상속

class Calculator : public Adder, public Subtractor {

public:

int calc(char op, int a, int b);

};

int Calculator::calc(char op, int a, int b) { int res=0;

switch(op) {

case '+' : res = add(a, b); break;

case '-' : res = minus(a, b); break;

}

return res;

}

(58)

다중 상속 문제점

상속되는 두 클래스에 동일한 멤버 변수가 존재할 경우

class SuperA { public:

int x;

void sub() { cout<<“SuperA 의 sub()”<<endl;

} };

class SuperB { public:

int x;

void sub() { cout<<“SuperB 의 sub()”<<endl;

} };

class Sub: public SuperA, public SuperB { };

int main() { Sub obj;

obj.x = 10; //?

return 0;

}

(59)

다중 상속 문제점

상속되는 두 클래스에 동일한 멤버 변수가 존재할 경우 에 , 그 변수 앞에 ::’ ‘ 를 이용하여 해당 클래스 이름을 명시해야 함

class SuperA { public:

int x;

void sub() { cout<<“SuperA 의 sub()”<<endl;

} };

class SuperB { public:

int x;

void sub() { cout<<“SuperB 의 sub()”<<endl;

} };

class Sub: public SuperA, public SuperB { };

int main() { Sub obj;

obj.SuperA::x = 10;

return 0;

}

참조

관련 문서

correlation analysis), 3개 이상의 변수들 간의 관계에 대한 강도를 측정하는 다중상관분석 (multiple

§ 회귀분석 (regression analysis)이란 하나의 종속변수와 하나 또 는 2개 이상의 독립변수들 간의 관련성을 규명할 수 있는 수학 적 모형을 측정된 변수들의

Confidence에 따른 정밀도 – mAP(mean Average precision) 계산... COCO Challenge – mAP(mean

역할은 두 개체 클래스가 하나 이상의 관계 타입과 연결되거나, 하 나의 관계 타입이 개체 클래스 자신과 연결된 상황에서 중요. 한 사람은 1명

 관계된 개체 클래스들이 관계성을 통해 하나의 릴레이션 으로 합병.  개체 클래스 Employee와 Store가 Manages 관계성을 통해

• 애플리케이션의 여러 자원들과 메인 프레임 클래스, View 클래스, Document 클래스 등을 하나의 묶 음으로 가지는

 다중 접근(Multiple Access): 노드나 지국이 다중점 또는 브로드캐스트 링크라고 부르는 공유 링크를 사용할 때 링크 에 접근하는 것을 조율하기 위한 다중 접근

 클래스계층 공유어프로치에서는, 부모(parent)클래스에 정의되어 있는 정보의 조작은 자식(child)클래스에서 정의되지 않고, 정의되지 않은 나머지 것만을