객체 지향 프로그래밍(Object-Oriented Programming, OOP) : 프로그래밍 패러다임의 하나로 프로그램을 객체들의 모임으로 보고 개발하는 것이다. 유연하고 변경이 용이하여 대규모 소프트웨어 개발에 많이 사용된다.
장점
* 유연하고 변경이 용이하다. (프로그램의 구조를 파악하기 쉬워 개발과 보수가 간편)
단점
* 지나치게 객체화 하는 것은 실제의 개념과 너무 달라서 이해하기가 쉽지 않아질 수 있다.
특성
* 크게 다음 네가지의 동작 과정이 있다.
- 클래스(class) : 추상 자료형(빵틀)
- 객체(object) : 추상 자료형의 인스턴스(빵틀을 통해 만들어진 빵)
- 메소드(method) : 추상 자료형에 정의된 연산(빵을 자르는 명령)
- 메시지(message) : 메소드의 호출(빵을 자르는 명령을 실행)
* 클래스는 정보은닉(Data Hiding)을 위해 캡슐화(Encapsulation)를 지향해야 한다.
: 내부 구현내용은 보이지 않도록 하고 약속된 부분만을 보이도록 지정한다.
=> 새로운 클래스에서 약속되지 않은부분을 추측해서 개발 했을 경우 문제가 발생할 수 있다.
* 기존 클래스의 기능을 상속(Inheritance)받는다.
: 하위 클래서에서는 기존 기능을 응용해 추가적인 요구사항을 개발할 수 있다.
=> 클래스간의 종속관계를 형성시켜 객체를 조직화할 수 있고 소스코드의 재사용성을 더해준다.
* 2개 이상의 클래스로부터 상속받을 수 있다.(다중상속)
=> 클래스의 상속관계에 혼란을 줄 수 있으므로 주의해야한다.
* 다형성(polymorphism)을 위해 다음과 같은 개념을 사용한다.
: 객체의 메소드를 여러가지 개념으로 사용 되도록 할 수 있다.
=> 클래스의 상속관계에서 가상함수(Virtual Functions)를 사용
=> 메소드를 오버라이딩(Overriding - 같은 이름의 메소드가 여러 클래스에서 다른기능을 하는것)
※ 오버라이딩을 위해 순수가상함수(Pure Virtual Functions)를 정의한다.
※ 순수가상함수가 1개 이상 선언된 클래스를 추상클래스(Abstract Class)라 부른다.
=> 메소드를 오버로딩(Overloading - 같은 이름의 메소드가 인자의 갯수나 자료형에 따라서 다른 기능을 하는것)
#include "stdafx.h"
#include <iostream>
using namespace std;
// Ex1> 클래스(Class)의 선언
class Dot
{
public:
Dot();
// Ex2> 생성자 Dot을 오버로딩(Overloading) 한다.
Dot(int x, int y)
{
this->x = x;
this->y = y;
}
int x;
int y;
// Ex3> 가상함수(Virtual Functions)를 선언한다.
virtual int Cal()
{
return this->x - y;
}
// Ex4> 일반 멤버함수를 선언한다.
void NotVirtual()
{
cout << "DOT CALL\n";
}
// Ex5> 순수가상함수(Pure Virtual Functions)를 선언한다.
virtual void PureVirtual() const = 0;
};
// Ex6> Dot 클래스를 상속(Inheritance) 받는다.
class DotA:public Dot
{
public:
DotA();
DotA(int x, int y);
// virtual는 생략가능하다.
virtual int Cal()
{
return this->x + this->y;
}
void NotVirtual()
{
cout << "DOTA CALL\n";
}
virtual void PureVirtual() const
{
cout << "DOTA CALL\n";
}
};
DotA::DotA(int x, int y):Dot(x, y)
{
cout << "SET DotA\n";
}
class DotB :public Dot
{
public:
DotB();
DotB(int x, int y);
// virtual는 생략가능하다.
virtual int Cal()
{
return this->x * this->y;
}
void NotVirtual()
{
cout << "DOTB CALL\n";
}
virtual void PureVirtual() const
{
cout << "DOTB CALL\n";
}
};
DotB::DotB(int x, int y) :Dot(x, y)
{
cout << "SET DotB\n";
}
int _tmain(int argc, _TCHAR* argv[])
{
// 가상함수의 사용
Dot* dot[2] = {};
// Ex7> 객체 생성
dot[0] = new DotA(100, 20);
dot[1] = new DotB(100, 20);
cout << "\n######## Virtual Functions ########\n";
// 가상함수의 사용
cout << "DotA Result : " << dot[0]->Cal() << "\n";
cout << "DotB Result : " << dot[1]->Cal() << "\n";
cout << "\n######## Member Functions ########\n";
// 일반멤버함수의 사용
dot[0]->NotVirtual();
dot[1]->NotVirtual();
cout << "\n######## Pure Virtual Functions ########\n";
// 순수가상함수의 사용
dot[0]->PureVirtual();
dot[1]->PureVirtual();
// Ex8> 추상클래스(Abstract Class) 생성
// 순수가상함수"virtual void PureVirtual() const = 0;"를 선언하므로써 Dot은 추상클래스(Abstract Class)가 되었다.
// 즉, 추상클래스는 말그대로 추상화된 클래스(구체화 되지않은 클래스)이기 때문에 상속받아 구현을 해야만 사용할 수 있다.
// Error - 추상클래스를 상속받은 클래스를 생성하지 않고 그냥 생성하였다.
// Dot dotTest = new Dot(100, 20);
return 0;
}
Ex1> 클래스(Class) 선언
Ex2> 오버로딩(Overloading)
Ex3> 가상함수(Virtual Functions) 선언
Ex4> 멤버함수 선언
Ex5> 순수가상함수(Pure Virtual Functions) 선언
Ex6> 클래스 상속(Inheritance)
Ex7> 객체(object) 생성
Ex8> 추상클래스(Abstract Class) 생성