객체를 생성 할 수 있는 클래스
모든 멤버 함수가 구현되어 있어야 함
객체를 생성할 수 없는 클래스
상속 계층구조에서 기본 클래스로 사용됨
아주 일반적이어서 객체를 생성하기엔 맞지 않는 경우
추상 클래스는 하나 이상의 “순수 가상 함수”를 갖는다.
즉, “순수 가상 함수”가 있는 클래스는 추상 클래스이다.
멤버 함수의 선언 뒤에 “= 0”을 붙이면 순수 가상 함수가 된다.
유도 클래스들은 반드시 기본 클래스의 순수 가상 함수를 오버라이드 해야 함
- 오버라이드 하지 않는 경우 , 유도 클래스도 추상 클래스로 간주됨
- 즉, 유도 클래스에서 특정 함수 구현을 “강제”하는 의미를 가짐
virtual void function() = 0; // body가 없는 순수 가상 함수
class Entity
{
protected:
int x, y;
public:
Entity(int x, int y)
:x{ x }, y{ y } {}
virtual ~Entity()
{
std::cout << "Entity 소멸자 호출됨" << std::endl;
}
virtual void Move(int dx, int dy) = 0; // 순수 가상 함수, 즉 Entity는 추상 클래스가 된다.
virtual void PrintPosition() const
{
std::cout <<"Entity : " << x << "," << y << std::endl;
}
};
💡 왜 오버라이드를 해줘야 하는가?이제 위의 Entity class는 추상 클래스가 되어 객체를 생성 할 수가 없어졌다. 이제 Derived class에서 추상 클래스의 내용을 오버라이드 해줘야 한다.
#include <iostream>
class Entity
{
protected:
int x, y;
public:
Entity(int x, int y)
:x{ x }, y{ y } {}
virtual ~Entity()
{
std::cout << "Entity 소멸자 호출됨" << std::endl;
}
virtual void Move(int dx, int dy) = 0; // 순수 가상 함수, 즉 Entity는 추상 클래스가 된다.
virtual void PrintPosition() const
{
std::cout <<"Entity : " << x << "," << y << std::endl;
}
};
class Player : public Entity
{
private:
int hp;
int xp;
public:
Player() = default;
Player(int x, int y ,int hp , int xp)
:Entity{x,y},hp{hp},xp{xp}{}
virtual ~Player()
{
std::cout << "Player 소멸자 호출됨" << std::endl;
}
virtual void Move(int dx, int dy) override //오버 라이드 완료
{
x += dx * 2;
y += dy * 2;
}
virtual void PrintPosition() const override
{
std::cout << "Player : " << x << "," << y << std::endl;
}
};
class temp : public Player {
private:
int t;
public:
temp(int x)
:Player{0,0,0,0},t {x}{}
};
int main()
{
Player p{ 1,1,1,1 }; // 생성 가능
}
class Entity
{
protected:
int x, y;
public:
Entity(int x, int y)
:x{ x }, y{ y } {}
virtual ~Entity()
{
std::cout << "Entity 소멸자 호출됨" << std::endl;
}
virtual void Move(int dx, int dy) = 0; // 순수 가상 함수, 즉 Entity는 추상 클래스가 된다.
virtual void PrintPosition() const
{
std::cout <<"Entity : " << x << "," << y << std::endl;
}
};
class Player : public Entity
{
private:
int hp;
int xp;
public:
Player() = default;
Player(int x, int y ,int hp , int xp)
:Entity{x,y},hp{hp},xp{xp}{}
virtual ~Player()
{
std::cout << "Player 소멸자 호출됨" << std::endl;
}
virtual void Move(int dx, int dy) override //오버 라이드 완료
{
x += dx * 2;
y += dy * 2;
}
virtual void PrintPosition() const override
{
std::cout << "Player : " << x << "," << y << std::endl;
}
}
int main()
{
Player p{ 1,1,1,1 }; // 생성 가능
Entity* eptr = new Player{ 1,1,10,10 }; //가능!
eptr->Move(2,2);
eptr->PrintPosition();
}
순수 가상 함수”만”을 가진 추상 클래스를 인터페이스 클래스라 한다.
클래스의 사용에 있어서 일반적인 기능을 묶어 놓은 클래스
인터페이스 클래스를 기반으로 한 구상 클래스는 모든 기능( 함수/ 서비스)를 구현해야 함
인터페이스는 껍데기다
유도 클래스가 꼭 가져야 하는 기능들을 명시해 놓기 위해서 사용
통상적으로 인터페이스 클래스의 이름을 지을 때는 대문자 I를 앞에 붙인다.
class IShape { //순수 가상 함수만을 가진 Interface Class
public:
virtual void draw() = 0;
virtual void rotate() = 0;
virtual ~Shape();
};
class Circle : public IShape { // interface class를 상속받은 구상 클래스
public:
virtual void draw() override {
//Implemetation
}
virtual void rotate() override {
//Implemetation
}
virtual ~Circle();
};