#include <iostream>
#include <string>
using namespace std;

class Animal
{
protected:
	string m_name;

public:
	Animal(std::string name)
		: m_name(name)
	{}
	
public:
	string getName() { return m_name; }
	
	virtual void speak() const = 0; // pure virtual function // 상속 구조를 한꺼번에 설계
};

//void Animal::speak() const // the body of the pure virtual function
//{
//	cout << m_name << " ??? " << "\n";
//} // 구현 해봤자 쓸 수가 없다.

class Cat : public Animal
{
public:
	Cat(string name)
		: Animal(name)
	{}
	
	void speak() const
	{
		cout << m_name << " Meow " << "\n";
	}
};

class Dog : public Animal
{
public:
    Dog(string name)
        : Animal(name)
    {}
    
    void speak() const
    {
        cout << m_name << " Woof " << "\n";
    }
};

class Cow : public Animal
{
public:
    Cow(string name)
        : Animal(name)
    {}
    
    void Animal::speak() const // the body of the pure virtual function
	{
		cout << m_name << " Moooo " << "\n";
	} 
};


int main()
{	
    //Animal ani("Hi"); 추상 클래스는 pure virtual function이 하나라도 있으면 인스턴스를 만들 수 없다.
    
    Cow cow("hello"); // Animal 클래스의 speak 함수를 override 안해주면 생성 불가능.
    cow.speak(); 
    return 0;
}

인터페이스 클래스

#include <iostream>
#include <string>
using namespace std;

class IErrorLog
{
public:
    virtual bool reportError(const char * errorMessage) = 0;
    
    virtual ~IErrorLog() {}
};

class FileErrorLog : public IErrorLog
{
public:
    bool repotError(const char * errorMessage) override
    {
        cout << "Writing error to a file" << "\n";
        return true;
    }
};

class ConsoleErrorLog : public IErrorLog
{
public:
    bool reportError(const char * errorMessage) override
    {
        cout << "Printing error to a console" << "\n";
        return true;
    }
};

void doSomething(IErrorLog & log)
{
    log.reportError("Runtime error!!");
}

int main()
{
    FileErrorLog file_log;
    ConsoleErrorLog console_log;
    
    doSomething(file_log);
    doSomething(console_log);
    
    return 0;
}

외부에서 사용할 때 이러이러한 기능이 있을거다 하는 역할을 하는 클래스