[c++] 상속 클래스

상속 : 이미 존재하고 있는 클래스로부터 새로운 클래스를 파생시킴

- class : public

- 클래스는 클래스에서 상속됨

- : 기본클래스, 부모클래스

- : 파생클래스, 자식클래스, 확장클래스, 서브클래스

- is-a 관계

- 자식클래스는 부모클래스로부터 접근 가능 데이터 필드와 함수를 상속받음

(생성자, 소멸자는 상속X)

- 자식클래스에서는 상속 받은 것 외에도 새로운 데이터 필드나 함수를 추가할 수도 있음

 

#inndef ... #define ... ~~~ #endif

- 복수 선언이 일어나지 않도록

 

일반화 프로그래밍

- 부모 클래스 유형의 객체가 요구되는 곳이면 어디에서든지 자식 클래스의 객체도 사용 가능

void displayGeometricObject(GeometricObject shape) {

        cout << shape.toString() << endl;

}

displayGeometricObejct(GeometricObject("black", true));

= displayGeometricObejct(Circle(5));

= displayGeometricObejct(Rectangle(2,3));

 

생성자와 소멸자

- 자식 클래스는 부모 클래스로부터 접근 가능 데이터 필드와 함수를 상속받음

- 생성자, 소멸자는 상속되지 않음

- 부모 클래스의 데이터 필드를 초기화하기 위해서 자식 클래스의 생성자로부터 호출됨

    >> 부모 클래스 : 인수있는 생성자, 인수없는 생성자    

    >> 자식 클래스의 생성자가 부모 클래스를 부름!

    >> !!

- 명시적으로 호출되지 않는다면 기본적으로 부모 클래스의 인수 없는 생성자가 호출됨

    >> 부모 클래스에 인수 없는 생성자 없이 인수 있는 생성자를 쓰면 오류 확률 높음

- 클래스 선언이 아닌 클래스 구현에서 호출함

Circle::Circle(double radius, string color, bool filled) : GeometricObject(color, filled) {

            this -> radius = radius;

}

 

생성자와 소멸자의 연쇄적 처리

자식 객체를 생성하면

: 부모 생성자 -> 자식 생성자 -> 자식 소멸자 -> 부모 소멸자

 

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

- 자식 클래스에서 가상함수를 재정의하는 것

- 자식 클래스에서 부모 클래스를 재정의 하기 위해서는 자식 클래스의 헤더 파일에 함수의 원형을 추가하고 자식 클래스의 구현 파일에서 함수에 대한 새로운 구현을 하면 됨

- 지역변수가 우위를 갖는 것처럼!

 

string GeometricObject::toString() {

        return "Geometric object color " + color + "filled" + ((filled) ? "true" : "false");

}

string Circle::toString() {

        return "Circle object";

}

 

GeometricObject shape;

Circle circle(5);

cout << shape.toString();

cout << circle.toString();

cout << circle.GeometricObject::toString();

 

:: 기본 클래스 이름의 영역 결정 연산자

- 오버라이딩 후 자식 클래스에서 부모 클래스를 사용할 때

 

>> pop! 되어버림 Call by value

- virtual 키워드 사용

- 포인터나 참조변수 이용

public:

virtual string toString() {

return "class C";

}

...

void displayObject(c *p) { // 포인터

        cout << p->toString().data() << endl;

        // (*p).toStirng

}

... displayObject(&a);

 

=

 

void displayObject(c &p) {

        cout << p.toStirng().data() << endl;

}

... displayObject(a);

 

 

동적 결합 dynamic binding

: 실행 시에 어떤 함수가 호출될 지를 결정

- 런타임 전에는 어느 객체가 넘어가는지 몰라 (컴파일러가 모름)

* dynamic static

 

virtual : 부모 클래스에서 정의하면 자동적으로 모든 자식 클래스에서도 virtual이 됨

- 함수가 재정의 되지 않을 것이라면 가상으로 선언하지 않는 것이 더 효과적

>> 실행 시에 동적으로 가상 함수들을 결합하는 데 더 많은 시간과 시스템 자원이 사용되기 때문

 

가시성, 접근성 수식자

protected 키워드

private : 클래스 안에서만 접근 가능

public : 다른 클래스로부터 접근 가능

protedcted : 자식 클래스에서 이름으로 접근 가능



부모 클래스 - 좀 덜 구체적인 상태, 일반적 특징 포함

자식 클래스 - 좀 더 구체적인 상태

 

추상 함수 = 순수 가상 함수

추상 클래스

- 부모 클래스가 너무 추상적이어서 어떤 특정 인스턴스를 가질 수 없는 클래스

- 순수 가상함수를 포함하는 클래스

- 객체를 생성할 수 없다는 것을 제외하고 보통 클래스와 같음

- 추상 클래스가 객체를 생성하려하면 컴파일러는 오류를 발생시킴

- 자식 클래스가 객체를 만듦!

 

순수 가상함수 : virtual double getArea() = 0;

- =0

- 순수 가상함수는 부모 클래스에서 함수의 본체나 구현을 가질 수 없음

- 바디는 자식 클래스에서 구현

 

업캐스팅 : 자식 클래스 유형의 포인터를 부모 클래스 유형의 포인터로 할당하는 것

- 암시적 수행

다운캐스팅 : 부모 클래스 유형의 포인터를 자식 클래스 유형의 포인터로 할당하는 것

- 명시적으로 수행해야 함

 

GeometricObejct *p = new Circle(1);

Circle *p1 = new Circle(2);

p = p1;

p1 = dynamic_cast<Circle>(p);

 

 

반응형
그리드형

댓글

❤️김세인트가 사랑으로 키웁니다❤️