<클래스 상속>
이미 정의된 클래스의 멤버를 새롭게 정의할 클래스의 멤버로 참조케 하는 것을 말합니다.
즉, 이미 작성한 클래스의 멤버를 물려받는 것입니다.
부모 클래스/기반 클래스 와 자식 클래스/파생 클래스 라고 얘기합니다.
class 자식클래스 : 접근지정자 부모클래스
{
멤버 변수와 함수 선언;
};
자식 클래스의 객체는 부모 클래스의 멤버를 새롭게 정의하지 않아도 멤버 참조가 가능합니다. (private 제외)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <iostream> #include <string> using namespace std; class Figure //부모 클래스 { public: void setColor(const string color); string getColor(); private: string color; }; class Circle : public Figure //자식 클래스 { void setRadius(const double r); double getArea(); private: double radius, area; }; int main() { Figure f; Circle c; } | cs |
이렇게 Circle class는 Figure class를 상속 받고 있습니다.
Circle class의 객체인 c는 당연히 setRadius(), getArea(), radius, area를 참조할 수 있습니다.
또한 부모 class의 setColor(), getColor()를 참조할 수 있습니다. private인 color는 Figure의 객체에서만 참조할 수 있습니다.
Figure class의 객체인 f는 setColor(), getColor(), color를 참조할 수 있지만, 자식 class의 멤버 변수나, 멤버 함수는 참조할 수 없습니다.
<함수 오버라이딩>
부모 클래스의 멤버 함수를 자식 클래스에서 다시 정의하는 것을 말합니다.
- 동적 결합
실행 시 호출될 함수를 결정하는 것으로 하나의 함수가 여러 클래스에서 오버라이딩 되었을 때 사용합니다.
- 다형성
하나의 함수가 여러 구현 형태로 정의되는 것입니다.
다형성에 의해 함수 재정의시 요구 조건은 부모 클래스의 멤버 함수가 가상함수로 선언되어 있어야 하고, 매개변수로 전달된 변수는 객체의 주소를 포함해야 하는 것입니다.
- 가상 함수
함수 오버라이딩을 목적으로한 부모 클래스의 함수입니다.
virtual 반환형 함수이름();
이렇게 선언합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <iostream> #include <string> using namespace std; class A { public: string classMessage() { return "class A"; } }; class B : public A { public: string classMessage() { return "class B"; } }; void TestFunc(A x) { cout << x.classMessage() << endl; } int main() { A a; B b; TestFunc(a); TestFunc(b); return 0; } | cs |
실행 결과는 이렇습니다.
객체 b를 넘겨줬고, 함수는 오버라이딩 되어서 호출했을 때 class B의 classMessage() 함수를 호출할 거라고 생각했지만, 결과는 class A가 두 번 출력되었습니다.
매개 변수에 class A를 따르는 객체를 받아와서 class A에서만 참조하기 때문입니다. 그래서 자식 클래스를 절달해도 해당 클래스의 함수를 호출한 것입니다.
그럼 동적 결합을 해야하는데요.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | #include <iostream> #include <string> using namespace std; class A { public: virtual string classMessage() { return "class A"; } }; class B : public A { public: string classMessage() { return "class B"; } }; void TestFunc(A *x) { cout << x->classMessage() << endl; } int main() { A a; B b; TestFunc(&a); TestFunc(&b); return 0; } | cs |
A class의 함수를 가상 함수로 만들어서 다형성을 지원해줍니다.
그리고 매개 변수로 객체의 주소를 받고, 포인터이기 때문에 . 연산자가 아닌 -> 연산자를 사용했습니다.
그러면 동적 결합이 잘 돼서 우리가 원하는 결과가 출력됩니다.
<추상 클래스>
객체 생성이 목적이 아닌 클래스입니다.
상속에서 부모 클래스 역할을 담당하고 순수 가상 함수를 포함합니다.
- 순수 가상 함수
함수 내용을 정의하지 않고 자식 클래스에서 함수 오버라이딩에 의해 내용이 결정되는 형태의 함수입니다.
virtual 반환형 함수이름() = 0;
이렇게 선언합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <iostream> #include <string> using namespace std; class AbstractClass { public: virtual string SampleFunction() = 0; }; class TestClass : public AbstractClass { public: string SampleFunction() { return "SampleFunction"; } }; int main() { AbstractClass obj1; //추상 클래스는 객체를 생성하지 못해서 error cout << obj1.SampleFunction() << endl; return 0; } | cs |
추상 클래스는 객체를 생성하지 못합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <iostream> #include <string> using namespace std; class AbstractClass { public: virtual string SampleFunction() = 0; }; class TestClass : public AbstractClass { public: string SampleFunction() { return "SampleFunction"; } }; int main() { TestClass obj1; cout << obj1.SampleFunction() << endl; return 0; } | cs |
error가 발생하지 않습니다.
실행해보면 결과가 잘 출력됩니다.
추상 클래스는 아직 너무 추상적이여서 객체화 할 수 없을 때 사용합니다.
'Programming > C++' 카테고리의 다른 글
[C++] 파일 입출력 fstream (0) | 2018.01.22 |
---|---|
[C++] string 클래스 (0) | 2018.01.22 |
[C++] this (0) | 2018.01.22 |
[C++] 객체 포인터 (0) | 2018.01.22 |
[C++] 소멸자 (0) | 2018.01.22 |