quiz - 추상클래스 Employee예제

객체지향 다형성

: 자식들을 부모타입의 배열로 묶어 관리하거나, 부모타입의 매개변수로 자식 객체를 받을 수 있다.
그리고 실행은 각 자식객체의 메서드가 실행된다 !

package ex03.inheritance.employee04;

/**
 * @author bitcamp1
 *이 클래스의 역할을 main를 사용하여
 *프로그램의 시작부분을 담당한다
 */
public class EmployeeMain {
	public static void main(String[] args) {
		EmployeeView view = new EmployeeView();
		view.menuLoop();
	}
}
package ex03.inheritance.employee04;

/** 추상클래스의 특징
 * 1) 추상메서드를 1개 이상 포함하고 있다
 * 2) 추상메서드는 구현이 되지않은 메서드이다
 * 3) 추상클래스는 객체를 만들 수 없다
 * 4) 추상클래스를 상속받은 자식 클래스가
 *    추상메서드를 구현하지 않으면
 *    자식 클래스도 추상클래스가 된다
 * 
 *  추상클래스의 목적
 * 1) 일부 필드와 메서드는 미리 구현하여서 상속하지만
 *    추상메서드는 미리 정의할 수 없어서 자식클래스로
 *    하여금 구현을 강요하도록 한다
 * 2) 추상클래스를 상속받은 모든 클래스는
 *    부모인 추상클래스 변수를 통해 
 *    메서드의 매개변수로 전달하여 메서드의 양을
 *    줄이는 효과가 있다.
 * 3) 추상클래스를 상속받은 모든 클래스는
 *    부모인 추상클래스 변수의 배열에 
 *    자식 클래스의 객체들을 담아서 각각 다른 클래스
 *    객체를 통일성있게 관리할 수 있다.
 * @author bitcamp1
 *
 * 사원 클래스
 * 상속을 전제로 한 추상 클래스
 * 급여는 사원들의 종류에 따라 다르게 계산되므로
 * 미리 구현하지 않고 사원에 따라 다르게 구현되도록
 * 추상클래스와 추상메서드를 사용하였다.
 * 
 * 명사형 클래스
 * VO(Value Object), DTO(Data Transfer Object)
 * MVC에서는 Model로 지칭될 수 있다
 * DBMS에서는 테이블/뷰와 상응관계가 된다.
 */
public abstract class Employee {
	protected String empno;	// 사번
	protected String name;	// 이름
	protected int pay;		// 연봉/일당
	
	/** 객체가 생성될 때 생성자를 통해 초기화하도록 하는 기능
	 * @param empno	사번
	 * @param name	사원이름
	 * @param pay	사원연봉/일당
	 */
	public Employee(String empno, String name, int pay) {
		this.empno = empno;
		this.name = name;
		this.pay = pay;
	}
	
	/** 추상메서드로서 자식클래스들이 각각 구현해야 하는 메서드
	 * @return 급여
	 */
	public abstract double getMonthPay();
	
	/**
	 * 사원정보를 출력하는 기능
	 */
	public void showEmployeeInfo() {
		System.out.println("empno: " + empno);
		System.out.println("name: " + name);
		System.out.println("pay: " + pay);
	}
	
	/**
	 * 사원정보 + 월급정보 출력하는 기능
	 */
	public void showMonthPayInfo() {
		showEmployeeInfo();
		System.out.println("monthPay: " + getMonthPay());
		System.out.println("-----------------------");
	}
}
package ex03.inheritance.employee04;

import java.util.Scanner;

/**
 * @author bitcamp1
 * 화면에서 사용자의 선택에 대한 처리 기능들의 역할
 * 처리를 담당하는 클래스
 * (비즈니스 로직을 담당)
 * DB - Model - Controller - View - User
 * 
 * Controller
 * Service
 * Manager
 * Handler
 */
public class EmployeeController {
	
	private final int EMP_NUM = 100;
	private Employee[] employeeArr = new Employee[EMP_NUM];
	private int numOfEmployee = 0;	// 저장된 사원수
	
	/** Employee배열에 객체를 저장하는 기능
	 * @param emp Employee로부터 상속받은 클래스의 객체
	 * @return 저장되었는지 여부
	 */
	boolean saveEmployee(Employee emp) {
		if(numOfEmployee < employeeArr.length) {
			employeeArr[numOfEmployee++] = emp;
			return true;
		}else {
			return false;
		}
	}

	/** 정규직 저장 처리 기능
	 */
	void saveRegularEmployee() {
		String empno, name;
		int pay, bonus;
		
		// View에서 생성한 Scanner객체를 얻는다
		Scanner sc = EmployeeView.getScanner();
		System.out.print("사번: "); empno = sc.next();
		System.out.print("이름: "); name = sc.next();
		System.out.print("연봉: "); pay = sc.nextInt();
		System.out.print("보너스: "); bonus = sc.nextInt();
		
		// 정규직 클래스 객체를 생성한다
		RegularEmployee re = 
				new RegularEmployee(empno, name, pay, bonus);
		boolean isSave = saveEmployee(re);
		if(isSave)
			System.out.println("잘 저장되었습니다~");
		else
			System.out.println("더 이상 저장되지 않습니다!");
	}	
	/** 임시직 저장 처리 기능
	 */
	void saveTempEmployee() {
		String empno, name;
		int pay, hireYear;
		
		Scanner sc = EmployeeView.getScanner();
		System.out.print("사번: "); empno = sc.next();
		System.out.print("이름: "); name = sc.next();
		System.out.print("계약금: "); pay = sc.nextInt();
		System.out.print("고용 기간: "); hireYear = sc.nextInt();
		
		// 임시직 클래스 객체를 생성한다
		TempEmployee te = 
				new TempEmployee(empno, name, pay, hireYear);
		boolean isSave = saveEmployee(te);
		if(isSave)
			System.out.println("잘 저장되었습니다~");
		else
			System.out.println("더 이상 저장되지 않습니다!");
	}	
	/** 일용직 저장 처리 기능
	 */
	void savePartTimeEmployee() {
		String empno, name;
		int pay, workDay;
		
		Scanner sc = EmployeeView.getScanner();
		System.out.print("사번: "); empno = sc.next();
		System.out.print("이름: "); name = sc.next();
		System.out.print("일당: "); pay = sc.nextInt();
		System.out.print("일수: "); workDay = sc.nextInt();
		
		// 계약직 클래스 객체를 생성한다
		PartEmployee  pe =  
				new PartEmployee(empno, name, pay, workDay);
		boolean isSave = saveEmployee(pe);
		if(isSave)
			System.out.println("잘 저장되었습니다~");
		else
			System.out.println("더 이상 저장되지 않습니다!");
	}
	
	/**
	 * 전체 사원 정보 출력
	 */
	void printAllEmployeeInfo() {
		System.out.println("####################");
		for(int i=0;i<numOfEmployee;i++) {
			employeeArr[i].showEmployeeInfo();
			System.out.println();
		}
	}
	
	/**
	 * 전체 급여 정보 출력
	 */
	void printAllPayInfo() {
		System.out.println("####################");
		for(int i=0;i<numOfEmployee;i++) {
			employeeArr[i].showMonthPayInfo();
			System.out.println();
		}
	}
	
}
package ex03.inheritance.employee04;

import java.io.IOException;
import java.util.Scanner;

/**
 * @author bitcamp1 서비스 시작시 화면에 메뉴를 보여주고 사용자와 입출력을 담당한다. 처리와 사용자간의 중간 인터페이스 역할을
 *         담당한다
 */
public class EmployeeView {

	// controller에 구현된 처리 기능을 사용하기 위해
	// 객체를 생성하였다.
	EmployeeController controller = new EmployeeController();

	/**
	 * 직접 필드 sc를 접근하지 마라
	 */
	private static Scanner sc = new Scanner(System.in);

	/**
	 * sc를 간접 접근하기 위해 만든 메서드
	 * 
	 * @return 키보드 입력 객체
	 */
	static Scanner getScanner() {
		return sc;
	}

	/**
	 * 메뉴를 사용자한테 보여주는 기능
	 */
	void viewMenu() {
		System.out.println("*** 메뉴 선택 ***");
		System.out.println("1. 정규직 저장");
		System.out.println("2. 임시직 저장");
		System.out.println("3. 일용직 저장");
		System.out.println("4. 직원 정보 출력");
		System.out.println("5. 급여 정보 출력");
		System.out.println("6. 서비스 종료");
	}

	/**
	 * 사용자의 번호선택을 입력받는 기능
	 * 
	 * @return 선택 번호
	 */
	int getUserSelect() {
		System.out.print("번호를 선택하세요 >> ");
		return sc.nextInt();
	}

	/**
	 * 사용자의 선택에 따른 동작을 배정하는 기능 (EmployeeController클래스의 객체와 사용자간의 인터페이스 역할을 담당)
	 * 
	 * @param choice 선택 번호
	 * @return 루프의 반복 여부
	 */
	boolean runChoice(int choice) {
		boolean isRun = true;

		switch (choice) {
		case 1:
			controller.saveRegularEmployee();
			break;
		case 2:
			controller.saveTempEmployee();
			break;
		case 3:
			controller.savePartTimeEmployee();
			break;
		case 4:
			controller.printAllEmployeeInfo();
			break;
		case 5:
			controller.printAllPayInfo();
			break;
		case 6:
			System.out.println("안녕히 계세요 ^^");
			isRun = false;
			break;
		default: // else에 해당하는 구문
			System.out.println("잘 못 입력하셨습니다...");
			break;
		}

		return isRun;
	}

	/**
	 * 서비스의 시작시 화면을 반복해서 보여주는 기능
	 */
	void menuLoop() {
		boolean isRun = true;
		while (isRun) {
			clearScreen();
			viewMenu(); // 메뉴 출력
			int choice = getUserSelect();// 선택값
			isRun = runChoice(choice); // 선택에 따른 동작
		}
	}

	public final static void clearScreen()
	{
	    try
	    {
	        final String os = System.getProperty("os.name");

	        if (os.contains("Windows"))
	        {
	            Runtime.getRuntime().exec("cls");
	        }
	        else
	        {
	            Runtime.getRuntime().exec("clear");
	        }
	    }
	    catch (final Exception e)
	    {
	        //  Handle any exceptions.
	    }
	}

//		for (int i = 0; i < 80; i++)
//			System.out.println("");
}
package ex03.inheritance.employee04;

public class RegularEmployee extends Employee {

	private int bonus;
	
	public RegularEmployee(String empno, String name, int pay, int bonus) {
		super(empno, name, pay);
		this.bonus = bonus;
		
	}

	@Override
	public void showEmployeeInfo() {
		super.showEmployeeInfo();
		System.out.println("bonus : " + bonus);
	}

	@Override
	public double getMonthPay() {
		return (double)pay/12 + (double)bonus/12;	
		//pay와 bonus가 int형이니까 int로 나오기때문에  double로 바꿔줌.
	}
}
package ex03.inheritance.employee04;


public class TempEmployee extends Employee {
	
	private int hireYear;

	public TempEmployee(String empno, String name, int pay,int hireYear) {
		super(empno, name, pay);
		this.hireYear = hireYear;
	}

	@Override
	public double getMonthPay() {
		return (double)pay/12;
	}

	@Override
	public void showEmployeeInfo() {
		super.showEmployeeInfo();
		System.out.println("hireYear : " + hireYear);
	}
	
}
package ex03.inheritance.employee04;

public class PartEmployee extends Employee {
	
	private int workDay;

	public PartEmployee(String empno, String name, int pay, int workDay) {
		super(empno, name, pay);
		this.workDay = workDay;
	}

	@Override
	public double getMonthPay() {
		return pay*workDay;	//소수점이 나올 일이 없어서 double 형변환 안함 
	}

	
	@Override
	public void showEmployeeInfo() {
		super.showEmployeeInfo();
		System.out.println("bonus : " + workDay);
	}
}

좋은 웹페이지 즐겨찾기