전체 코드


✅ 1. 객체지향 프로그래밍(OOP)의 3대 특성

💡 OOP의 핵심 개념

개념설명
상속성(Inheritance)부모 클래스의 속성과 기능을 자식 클래스가 물려받는 것
은닉성(Encapsulation)중요한 정보를 외부로부터 숨기고, 제한된 방법으로만 접근할 수 있도록 하는 개념
다형성(Polymorphism)같은 이름의 함수가 다양한 객체에서 다르게 동작하도록 하는 개념

📌 다형성(Polymorphism)은 같은 이름을 가진 함수가 서로 다른 동작을 하도록 만드는 개념입니다. 이를 통해 코드의 재사용성을 높이고 유연한 설계를 할 수 있습니다.


📌 2. 다형성의 종류

📌 2.1. 오버로딩(Overloading)

  • 같은 이름의 함수를 여러 개 정의하는 것
  • 함수의 매개변수 개수나 타입이 다르면 다른 함수로 간주됨
  • 정적 바인딩(Static Binding)으로 컴파일 시점에 호출할 함수가 결정됨

📌 2.2. 오버라이딩(Overriding)

  • 부모 클래스의 함수를 자식 클래스에서 재정의하는 것
  • 가상 함수(virtual function)를 사용해야 함
  • 동적 바인딩(Dynamic Binding)으로 실행 시점에 호출할 함수가 결정됨

📌 2.3. 순수 가상 함수(Pure Virtual Function)

  • 함수의 구현 없이 선언만 존재하며, 자식 클래스에서 반드시 구현해야 함
  • 순수 가상 함수가 포함된 클래스는 "추상 클래스(Abstract Class)"가 됨
  • 추상 클래스는 직접 객체를 생성할 수 없음

📌 3. 코드 분석 (Player, Knight, Mage 클래스)

✅ 3.1 헤더 포함 및 네임스페이스 설정

#include <iostream>  // 입출력 기능 제공
using namespace std; // std:: 생략
  • #include <iostream> : cout, cin을 사용하기 위해 포함
  • using namespace std; : std::cout 대신 cout으로 사용 가능

✅ 3.2 Player 클래스 (부모 클래스 - 가상 함수 포함)

class Player
{
public:
    Player()
    {
        _hp = 100;
    }

    void Move() { cout << "Move Player !" << endl; }
    virtual void VMove() { cout << "VMove Player !" << endl; }
    virtual void VDie() { cout << "VDie Player !" << endl; }
    virtual void VAttack() = 0; // 순수 가상 함수

public:
    int _hp;
};

📌 Player 클래스 분석

  • Move()
    • 일반적인 함수 (정적 바인딩)
    • Player 객체의 포인터로 호출하면 항상 Move()가 실행됨
  • virtual void VMove() / virtual void VDie()
    • 가상 함수 (동적 바인딩)
    • Player 객체의 포인터로 호출하면 자식 클래스에서 오버라이딩된 함수가 실행됨
  • virtual void VAttack() = 0;
    • 순수 가상 함수 → 반드시 자식 클래스에서 재정의해야 함
    • 이 함수가 포함된 Player 클래스는 추상 클래스가 됨
    • Player 클래스의 객체는 직접 생성할 수 없음

✅ 3.3 Knight 클래스 (기사 - Player 상속 및 가상 함수 재정의)

class Knight : public Player
{
public:
    Knight()
    {
        _stamina = 100;
    }

    void Move() { cout << "Move Knight !" << endl; }
    virtual void VMove() { cout << "VMove Knight !" << endl; }
    virtual void VDie() { cout << "VDie Knight !" << endl; }
    virtual void VAttack() { cout << "VAttack Knight !" << endl; }

public:
    int _stamina;
};

📌 Knight 클래스 분석

  • Move() 함수
    • PlayerMove()를 오버라이딩 (정적 바인딩)
    • Player 포인터로 호출하면 Move()Player의 것이 실행됨
  • virtual void VMove() / virtual void VDie()
    • Player의 가상 함수를 오버라이딩 (동적 바인딩)
    • Player* 포인터로 호출하면 Knight의 함수가 실행됨
  • virtual void VAttack()
    • Player의 순수 가상 함수를 구현
    • VAttack()을 구현하지 않으면 Knight도 추상 클래스가 됨

✅ 3.4 Mage 클래스 (마법사 - Player 상속 및 가상 함수 재정의)

class Mage : public Player
{
public:
    virtual void VAttack() { cout << "VAttack Mage !" << endl; }

public:
    int _mp;
};

📌 Mage 클래스 분석

  • VAttack() 함수
    • Player의 순수 가상 함수를 구현
    • VAttack Mage! 출력
  • 멤버 변수 _mp
    • 마나(MP)를 관리

✅ 3.5 다형성 활용 (MovePlayer, MoveKnight)

void MovePlayer(Player* player)
{
    player->VMove();
    player->VDie();
}

📌 MovePlayer 함수

  • Player* 포인터를 받아 VMove()VDie()를 호출
  • Knight 또는 Mage 객체를 전달하면 실제 객체의 가상 함수가 실행됨
  • 동적 바인딩(Dynamic Binding) 적용
void MoveKnight(Knight* knight)
{
    knight->Move();
}

📌 MoveKnight 함수

  • Knight 객체의 Move()를 호출 (정적 바인딩)
  • Knight 객체에서만 사용 가능

📌 4. main() 함수 - 다형성 적용

int main()
{
    // Player p;    // Player는 추상 클래스이므로 객체 생성 불가

    Knight k;
    MovePlayer(&k); // 기사는 플레이어다? YES

    return 0;
}

📌 실행 흐름
1. Knight k; 객체 생성
2. MovePlayer(&k); 호출 → Player* 포인터로 Knight 객체 전달
3. MovePlayer() 내부에서 player->VMove(); 호출 → VMove Knight! 출력
4. player->VDie(); 호출 → VDie Knight! 출력

📌 출력 결과

VMove Knight!
VDie Knight!

📌 5. private, protected, public 차이점

접근 지정자클래스 내부자식 클래스외부
publicOOO
protectedOOX
privateOXX

📌 상속 접근 지정자
| 상속 타입 | 부모 public | 부모 protected | 부모 private |
|----------|-------------|---------------|---------------|
| public 상속 | public 유지 | protected 유지 | 접근 불가 |
| protected 상속 | protected 유지 | protected 유지 | 접근 불가 |
| private 상속 | private 변환 | private 변환 | 접근 불가 |


profile
李家네_공부방

0개의 댓글