2 minute read

08-1 [상속 관계의 확장과 추상클래스]

  • 코드💻
/*
 * 위험수당을 지급하는 ForeignSalesWorker 클래스를 정의하여 확장해보자
 * 위험수당은 위험의 노출도에 따라서 나뉘고, 한번 결정된 직원의 위험 노출도는 변경되지 않는다
 * Employee클래스는 추상클래스로 정의한다	
 */
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;

namespace RISK_LEVEL{
	enum
	{
		RISK_A, RISK_B, RISK_C
	};

	double RiskRatio(int risk) {
		switch (risk)
		{
		case RISK_A:
			return 0.3;
			break;

		case RISK_B:
			return 0.2;
			break;

		case RISK_C:
			return 0.1;
			break;

		default:
			break;
		}
	}
}

class Employee
{
private:
	char name[100];
public:
	Employee(const char* name)
	{
		strcpy(this->name, name);
	}
	void ShowYourName() const
	{
		cout << "name: " << name << endl;
	}
	virtual int GetPay() const = "0";
	virtual void ShowSalaryInfo() const ="0";
};

class PermanentWorker : public Employee
{
private:
	int salary;
public:
	PermanentWorker(const char* name, int money)
		: Employee(name), salary(money)
	{  }
	int GetPay() const
	{
		return salary;
	}
	void ShowSalaryInfo() const
	{
		ShowYourName();
		cout << "salary: " << GetPay() << endl << endl;
	}
};

class SalesWorker : public PermanentWorker
{
private:
	int salesResult;	  // 월 판매실적
	double bonusRatio;    // 상여금 비율 
public:
	SalesWorker(const char* name, int money, double ratio)
		: PermanentWorker(name, money), salesResult(0), bonusRatio(ratio)
	{  }
	void AddSalesResult(int value)
	{
		salesResult += value;
	}
	int GetPay() const
	{
		return PermanentWorker::GetPay()
			+ (int)(salesResult * bonusRatio);
	}
	void ShowSalaryInfo() const
	{
		ShowYourName();
		cout << "salary: " << GetPay() << endl << endl;
	}
};

class ForeignSalesWorker : public SalesWorker
{
public:
	ForeignSalesWorker(const char* name, int money, double ratio, int risk);
	~ForeignSalesWorker();

private:
	const int m_eRisk;			//위험노출도
public:
	int GetPay() const;
	int RiskPay() const;
	void ShowSalaryInfo() const;
};

ForeignSalesWorker::ForeignSalesWorker(const char* name, int money, double ratio, int risk)
	: SalesWorker(name, money, ratio), m_eRisk(risk)
{	}

ForeignSalesWorker::~ForeignSalesWorker()
{	}

int ForeignSalesWorker::GetPay() const
{
	return SalesWorker::GetPay() + RiskPay();

}
int ForeignSalesWorker::RiskPay() const {

	return SalesWorker::GetPay() * RISK_LEVEL::RiskRatio(m_eRisk);
}

void ForeignSalesWorker::ShowSalaryInfo() const
{
	ShowYourName();
	cout << "salary: " << SalesWorker::GetPay() << endl;
	cout << "risk pay: " << RiskPay() << endl;
	cout << "sum: " << GetPay() << endl << endl;
}

class EmployeeHandler
{
private:
	Employee* empList[50];
	int empNum;
public:
	EmployeeHandler() : empNum(0)
	{ }
	void AddEmployee(Employee* emp)
	{
		empList[empNum++] = emp;
	}
	void ShowAllSalaryInfo() const
	{

		for (int i = 0; i < empNum; i++)
			empList[i]->ShowSalaryInfo();

	}
	void ShowTotalSalary() const
	{
		int sum = 0;

		for (int i = 0; i < empNum; i++)
			sum += empList[i]->GetPay();

		cout << "salary sum: " << sum << endl;
	}
	~EmployeeHandler()
	{
		for (int i = 0; i < empNum; i++)
			delete empList[i];
	}
};

int main(void) {

    //회사 직원 급여 책임지는 곳이라 할 수 있음
	EmployeeHandler handler;

    //해외 영업자 등록
	ForeignSalesWorker* fseller1 = new ForeignSalesWorker("Hong", 1000, 0.1, RISK_LEVEL::RISK_A);
	fseller1->AddSalesResult(7000);     //영업실적
	handler.AddEmployee(fseller1);
	
	ForeignSalesWorker* fseller2 = new ForeignSalesWorker("Yoon", 1000, 0.1, RISK_LEVEL::RISK_B);
	fseller2->AddSalesResult(7000);
	handler.AddEmployee(fseller2);
	
	ForeignSalesWorker* fseller3 = new ForeignSalesWorker("Lee", 1000, 0.1, RISK_LEVEL::RISK_C);
	fseller3->AddSalesResult(7000);
	handler.AddEmployee(fseller3);

    //이번달 지급해야할 급여 정보
	handler.ShowAllSalaryInfo();
	return 0;
}
  • 해외영업사원도 영업사원이므로 SalesWorker클래스를 상속받도록 했다.

  • 상속은 잘만 활용한다면 코드의 확장성 부분에 아주 좋은 것 같다. 그러기 위해선 높은 클래스(기초클래스)일수록 멤버 변수와 함수가 어느 정도 범위의 범용성을 갖게 할지 잘 정해야 할 것 같은데 쉬울 것 같진 않다.

  • 동시에 클래스는 유도클래스를 생각해보았을 때, 당장 필요한 것만으로 채울 수도 없는 것 같다. 어떤 기능과 변수가 필요할지, 어디까지 정의해놓는 것이 좋을 지, 포함관계를 고려하여 최적화 시키고 나중에 수정할 이유를 줄이도록 해야할 것 같다.

Tags: ,

Categories:

Updated: