본문 바로가기

게임개발 수업

OOP의 특징

oop란 Object Oriented Programming 의 줄임말로 영어 해석 그대로 객체를 지향하는 프로그래밍이라는 뜻이다.

 

oop를 왜 사용하는 것일까? 

- 프로그램의 유지 보수를 쉽게 하기 위해서 이다. 개발을 하다 보면 새로운 기능을 추가하기 위해, 혹은 버그를 수정하기 위해 등등 수없이 코드를 다시 수정해야 하는 일이 생긴다. oop는 이러한 과정을 좀 더 쉽게 하게 해준다.

 

ex) 강아지가 우는 프로그램을 만든다고 가정해보자

절차지향 객체지향
class Dog {
 public:
  string name;
  int age;
};

void cry(Dog dog) {
 cout << "멍멍";
}

int main() {
 Dog dog;
 cry(dog);
}
class Dog {
 public:
  string name;
  int age;

void cry() {
  cout << "멍멍";
}

};

int main() {
  Dog dog;
  dog.cry();
}

 

여기까지만 보면 별 차이가 없을 것이다. 하지만 이 상태에서 고양이가 우는 프로그램을 추가한다고 가정해보자.

절차지향 객체지향
class Dog {
 public:
  string name;
  int age;
};

class Cat {
 public:
  string name;
  int age;
};

void cry(Dog dog) {
  cout << "멍멍";
}

////(1) 새로운 함수를 만든다.
void cry(Cat cat) {
  cout << "냥냥";
}

//(2)파라미터를 템플릿 유형으로 받아서 처리한다.
template <class T>
void cry(T obj) {
  if (typeid(obj) == typeid(Dog)) {
    cout << "멍멍";
  }
  else if (typeid(obj) == typeid(Cat)) {
    cout << "냥냥";
  }
}

int main() {
 Dog dog;
//cry(dog);

 Cat cat;
 //cry(cat);
    
 cry(dog);
 cry(cat);
}
class Animal{
 public:
  virtual ~Animal() {}  // 가상 소멸자의 선언
  virtual void Cry() = 0; // 순수 가상 함수의 선언
};

class Dog : Animal {
 public:
  string name;
  int age;

  void Cry() {
   cout << "멍멍";
  }
};

class Cat : Animal {
 public:
  string name;
  int age;

  void Cry() {
   cout << "냥냥";
  }
};

int main() {
 Dog dog;
 dog.Cry();

 Cat cat;
 cat.Cry();
}

절차지향으로 구현 하면 똑같은 일을 하는 함수이지만, 객체에 따라 결과가 다르다는 이유로 함수를 새로 만들거나, 하나의 함수로 한다면 함수를 수정해야 한다.

 

하지만 객체지향에서는 객체가 하는 행동만 재정의(오버라이딩) 해주면 된다.

 

만약 구현해야 하는 동물이 100개나 된다면 어떻게 될까? 

절차지향에서는 100가지의 함수를 새로만들거나 수정해야 한다. 객체지향에서는 그저 객체를 추가하고 행동만 재정의 하면 된다.

 

이처럼 객체지향은 코드의 유지보수를 쉽게 해 준다.

 

그렇다면 객체란 무엇인가? 

 

- 객체란 말그대로 물체를 이야기한다. 현실세계를 추상화 하여 표현하는 표현 단위이다.지금 내 앞에 있는 핸드폰, 컴퓨터, 키보드, 물병 등등 모두 다 물체(객체)이다.하나의 물체는 하나의 객체라 할 수 있다.객체는 객체가 가지고 있는 정보와 객체가 할 수 있는 행동 2가지로 표현할 수 있다.

 

ex) 강아지

 

강아지 정보 - 키,몸무게,나이,견종 등등

강아지가 하는(할 수 있는) 행동 - 밥먹기, 잠자기, 짖기, 달리기 등등

 

이것들을 하나의 저장단위로 묶은 것을 객체라 하며 구조체, 클래스 등으로 표현할 수 있다.

(엄밀히 말하면 구조체,클래스는 객체를 만드는 설계도이다.)

 

class Dog(){

string name - 정보

void cry(); - 행동

}

 

OOP의 특징

 

1) 추상화

추상의 뜻 - 사물을 정확하게 이해하기 위해서는 사물이 지니고 있는 여러 가지 측면 가운데서 특정한 측면만을 가려내어 포착하는 것이다.

 

추상화란 사물이 갖고 있는 특징을 찾아내어 공통된 부분을 묶는 것을 말한다.

 

바둑이와 점박이라는 강아지가 있다고 하자.바둑이와 점박이는 각각 하나의 객체이다. 각각의 외모와 성격이 다르지만, 밥먹고 놀고 자고 짖고 한다는 공통된 특성을 가진 다는 것을 알고 있다.

 

이처럼 객체가 가진 특징을 잡아내서 표현하는 것을 추상화라고 한다.

 

class Dog(){

string name;

string chractor;

 

void cry();

void play();

void eat();

void sleep();

}

 

2)상속

바둑이와 점박이는 '개'라고 하는 생물학적 분류로 묶을 수 있지만, 크게 동물이라고 하는 분류로 묶을 수도 있다.

그리고 밥먹고 놀고 자고 짖고 하는 행동들은 '개'만 가진 특별한 행동이 아니라 동물이라면 모두가 갖고 있다.

 

그렇다면 동물이 가진 특징을 이어받은 '개'라고 하는 분류의 바둑이와 점박이라고 표현할 수 있다.

 

//동물의 특징

class Animal{
 public:
  virtual ~Animal() {} 
  virtual void cry() = 0; 

  virtual void play() = 0;

  virtual void eat() = 0;

  virtual void sleep() = 0;
};

 

//개

class Dog() : public Animal{

string name;

string chractor;

//생략

}

 

정보은닉과 캡슐화

바둑이와 점박이는 신나게 놀면 지치게 되고, 지치면 배고픔을 느낀다.

 

class Dog() : public Animal{

string name;

string chractor;

int stamina = 100;

 

 void play(){

  this.stamina-=10;

 }

 void eat(){

  this.stamina+=10;

 }

}

 

바둑이와 점박이는 각각의 스테미나 상태가 다르다.

아까 밥을 많이 먹은 바둑이는 스테미나가 높아 더 놀수 있고, 밥을 먹지 않은 점박이는 많이 놀지 못한다.

스테미나는 각각의 객체에 상태가 다른 것 입니다.

 

만약 누군가 강아지에게 최면을 걸어 스테미나 수치를 바꾸면 어떻게 될까?

점박이는 실제로 스테미나가 부족하지만 최면에 걸려 자신의 스테미나가 높다고 착각해 신나게 놀아버린다.

그러면 점박이는 병에 걸린다.

 

이렇듯 객체가 가진 상태정보를 외부에서 바꾸는 것은 위험하기 때문에 캡슐화로 정보를 숨기고,

객체가 하는 행동으로 정보를 바꾸는 것을 캡슐화 라고 한다.

 

//오직 play()와 eat()으로만 스테미나 정보를 바꿀 수 있다.

class Dog() : public Animal{

private:

string name;

string chractor;

int stamina = 100;

public:

 void play(){

  this.stamina-=10;

 }

 void eat(){

  this.stamina+=10;

 }

}

 

다형성

다형성이란 - 같은 종의 생물이지만, 모습이나 고유한 특징이 다양한 성질을 말한다.

점박이와 바둑이는 '개'라고 하는 같은 종이지만, 점박이는 리트리버이고, 바둑이는 보더콜리이다.

골든리트리버는 헤엄을 칠 수 있고, 바둑이는 양을 몰 수 있다.

 

이렇듯 각각의 객체에 여러 성질을 부여하는 것을 다형성이라 한다.

 

class Animal{
 public:
  virtual ~Animal() {} 
  virtual void cry() = 0; 

  virtual void play() = 0;

  virtual void eat() = 0;

  virtual void sleep() = 0;
};

 

//interface

class Iretriever{

virtual void swim() = 0; 

}

//interface

class  IborderCollie{

virtual void herd_sheep() = 0; 

}

 

//개

class Dog() : public Animal{

private:

string name;

string chractor;

int stamina = 100;

public:

 void play(){

  this.stamina-=10;

 }

 void eat(){

  this.stamina+=10;

 }

}

 

//'개'라는 종이지만 리트리버라는 특성을 가짐

class retriever : public Dog,Iretriever{

//생략

}

//'개'라는 종이지만 보더콜리라는 특성을 가짐

class borderCollie: public Dog,IborderCollie{

//생략

}

 

 

 

 

 

 

 

 

 

'게임개발 수업' 카테고리의 다른 글

클래스 생성자와 소멸자  (0) 2022.11.24
static 키워드  (0) 2022.11.23
STL vector  (0) 2022.11.08
STL 구성요소  (0) 2022.11.08
스택 프레임, 메모리 누수, 가비지 컬렉션, 메모리 단편화  (1) 2022.10.31