1. 程式人生 > >實戰專案助你掌握JavaSE知識

實戰專案助你掌握JavaSE知識

目標模擬實現一個基於文字介面的《團隊人員排程軟體》

熟悉Java面向物件的高階特性,進一步掌握程式設計技巧和除錯技巧

主要涉及以下知識點:

類的繼承和多型
物件的關聯
static和final修飾符
特殊類的使用
異常處理

需求說明:模擬實現基於文字介面的《團隊人員排程軟體》。

該軟體實現以下功能:
軟體啟動時,根據給定的資料建立公司部分成員列表(陣列)
根據選單提示,基於現有的公司成員,組建一個開發團隊以開發一個新的專案
組建過程包括將成員插入到團隊中,或從團隊中刪除某成員,還可以列出團隊中現在成員的列表
開發團隊成員包括架構師、設計師和程式設計師

本軟體採用單級選單方式工作。當軟體執行時,主介面顯示公司成員(部分)的列表,如下:
-------------------------------------開發團隊排程軟體--------------------------------------
ID     姓名      年齡    工資      職位      狀態      獎金      股票    領用裝置 
1      段譽      22        3000.0 
2      令狐沖  32        18000.0 架構師  FREE    15000.0  2000    聯想T4(6000.0) 
3      任我行  23        7000.0   程式設計師  FREE                               戴爾(NEC17寸) 
4      張三丰  24        7300.0   程式設計師  FREE                               戴爾(三星 17寸) 
5      周芷若  28        10000.0 設計師  FREE    5000.0                佳能 2900(鐳射) 
……
---------------------------------------------------------------------------------------------------
1-團隊列表  2-新增團隊成員  3-刪除團隊成員 4-退出   請選擇(1-4): _


當選擇“新增團隊成員”選單時,將執行從列表中新增指定(通過ID)成員到開發團隊的功能:
1-團隊列表  2-新增團隊成員  3-刪除團隊成員 4-退出   請選擇(1-4):2
---------------------新增成員---------------------
請輸入要新增的員工ID:2
新增成功
按回車鍵繼續...
新增成功後,按回車鍵將重新顯示主介面。
開發團隊人員組成要求:
最多一名架構師
最多兩名設計師
最多三名程式設計師
如果新增操作因某種原因失敗,將顯示類似以下資訊(失敗原因視具體原因而不同):
1-團隊列表  2-新增團隊成員  3-刪除團隊成員 4-退出   請選擇(1-4):2
---------------------新增成員---------------------
請輸入要新增的員工ID:2
新增失敗,原因:該員已是團隊成員
按回車鍵繼續...
失敗資訊包含以下幾種:
成員已滿,無法新增該成員不是開發人員,無法新增
該員已是團隊成員 
該員正在休假,無法新增
團隊中只能有一名架構師
團隊中只能有兩名設計師
團隊中只能有三名程式設計師


當選擇“刪除團隊成員”選單時,將執行從開發團隊中刪除指定(通過TeamID)成員的功能:
1-團隊列表  2-新增團隊成員  3-刪除團隊成員 4-退出   請選擇(1-4):2
---------------------刪除成員---------------------
請輸入要刪除員工的TID:1
確認是否刪除成功刪除(Y/N):y
按回車鍵繼續...
刪除成功後,按回車鍵將重新顯示主介面。


當選擇“團隊列表”選單時,將列出開發團隊中的現有成員,例如:
--------------------團隊成員列表---------------------
TID/ID  姓名    年齡    工資    職位    獎金    股票 
 2/4    張三丰  24      7300.0  程式設計師 
 3/2    令狐沖  32      18000.0 架構師  15000.0 2000
 4/6    趙敏    22      6800.0  程式設計師
 5/12   黃蓉    27      9600.0  設計師  4800.0
-----------------------------------------------------
1-團隊列表  2-新增團隊成員  3-刪除團隊成員 4-退出   請選擇(1-4):


軟體設計結構

該軟體由以下四個模組組成:


模組說明:
com.atguigu.team.view模組為主控模組,負責選單的顯示和處理使用者操作
com.atguigu.team.service模組為實體物件(Employee及其子類如程式設計師等)的管理模組, 
CompanyService和TeamService類分別用各自的陣列來管理公司員工和開發團隊成員物件

多層繼承:①提高程式碼的複用性②子類繼承父類後,子類理解為父類的特殊型別(多型)


com.atguigu.team.domain模組中包含了所有實體類:


其中程式設計師(Programmer)及其子類,均會領用某種電子裝置(Equipment)。


Employee類及其子類的設計



說明:
memberId 用來記錄成員加入開發團隊後在團隊中的ID
status是專案自定義的列舉型別,表示成員的狀態:
FREE-空閒
BUSY-已加入開發團隊
VOCATION-正在休假
equipment 表示該成員領用的裝置
可根據需要自行為類提供各屬性的get/set方法以及過載構造器

Status列舉類
Status列舉類位於com.atguigu.team.service包中.


說明:
bouns為獎金
stock表示公司獎勵的股票數量
可根據需要自行為類提供各屬性的get/set方法以及過載構造器

Equipment介面及其實現子類的設計


說明:
model表示機器的型號
display表示顯示器名稱
可根據需要自行為類提供各屬性的get/set方法以及過載構造器

CompanyService類的設計



說明:
employees用來儲存所有公司員工物件
CompanyService()構造器:
根據專案提供的Data類構建相應大小的employees陣列
再根據Data類中的資料構建不同的物件,包括Employee、Programmer、Designer和Architect物件,以及相關聯的Eqipment子類的物件
將物件存於陣列中
Data類位於com.atguigu.team.service包中
說明:
employees用來儲存所有公司員工物件
getAllEmployees ()方法:獲取當前所有員工。返回:包含所有員工物件的陣列
getEmployee(id : int)方法:獲取指定ID的員工物件。
引數:指定員工的ID
返回:指定員工物件
異常:找不到指定的員工
另外,可根據需要自行新增其他方法或過載構造器


TeamService類的設計


說明:
counter為靜態變數,用來為開發團隊新增成員自動生成團隊中的唯一ID,即memberId。(提示:應使用增1的方式)
MAX_MEMBER表示開發團隊最大成員數
team陣列用來儲存當前團隊中的各成員物件 
realCount記錄團隊成員的實際人數
getTeam()方法:返回當前團隊的所有有效物件
返回:包含所有成員物件的陣列,陣列大小與成員人數一致
addMember(e: Employee)方法:向團隊中新增成員
引數:待新增成員的物件
異常:新增失敗, TeamException中包含了失敗原因
removeMember(memberId: int)方法:從團隊中刪除成員
引數:待刪除成員的memberId
異常:刪除失敗, TeamException中包含了失敗原因
另外,可根據需要自行新增其他方法或過載構造器


TeamView類的設計


說明:
companySvc和teamSvc屬性:供類中的方法使用
enterMainMenu ()方法:主介面顯示及控制方法。
以下方法僅供enterMainMenu()方法呼叫:
listAllEmployees ()方法:以表格形式列出公司所有成員
addMember ()方法:實現新增成員操作
deleteMember ()方法:實現刪除成員操作

鍵盤訪問的實現

專案中提供了TSUtility.java類,可用來方便地實現鍵盤訪問。
該類提供了以下靜態方法:
public static char readMenuSelection()
用途:該方法讀取鍵盤,如果使用者鍵入’1’-’4’中的任意字元,則方法返回。返回值為使用者鍵入字元。
public static void readReturn()
用途:該方法提示並等待,直到使用者按回車鍵後返回。
public static int readInt()
用途:該方法從鍵盤讀取一個長度不超過2位的整數,並將其作為方法的返回值。
public static char readConfirmSelection() :
用途:從鍵盤讀取‘Y’或’N’,並將其作為方法的返回值。

第1步 — 建立專案基本元件

首先,完成以下工作:
建立TSS專案
按照設計要求,建立所有包
按照設計要求,在com.atguigu.team.domain包中,建立所有類和介面的宣告
將專案提供的幾個類複製到相應的包中
編寫Employee類及其各子類程式碼
編寫Equipment介面及其各實現子類程式碼
檢驗程式碼的正確性

第2步 — 實現service包中的類

按照設計要求編寫CompanyService類
在TeamMain類中的main方法中,寫單元測試。
在方法中建立CompanyService物件,然後分別用模擬資料呼叫該物件的各個方法,以測試是否正確。
注:測試應細化到包含了所有非正常的情況,以確保方法完全正確。
重複1-3步,完成TeamService類的開發

第3步 — 實現view包中類

按照設計要求編寫TeamView類,逐一實現各個方法,並編譯
執行main方法中,測試軟體全部功能

專案中提供的Status、Data、TSUtility的具體程式碼如下:

Status.java

<span style="font-size:18px;">public enum Status {
    FREE, BUSY, VOCATION
}</span>

Data.java
<span style="font-size:18px;">public class Data {
    public static final int EMPLOYEE = 10;
    public static final int PROGRAMMER = 11;
    public static final int DESIGNER = 12;
    public static final int ARCHITECT = 13;

    public static final int PC = 21;
    public static final int NOTEBOOK = 22;
    public static final int PRINTER = 23;

    //Employee  :  10, id, name, age, salary
    //Programmer:  11, id, name, age, salary
    //Designer  :  12, id, name, age, salary, bonus
    //Architect :  13, id, name, age, salary, bonus, stock
    public static final String[][] EMPLOYEES = {
        {"10", "1", "段譽", "22", "3000"},
        {"13", "2", "令狐沖", "32", "18000", "15000", "2000"},
        {"11", "3", "任我行", "23", "7000"},
        {"11", "4", "張三丰", "24", "7300"},
        {"12", "5", "周芷若", "28", "10000", "5000"},
        {"11", "6", "趙敏", "22", "6800"},
        {"12", "7", "張無忌", "29", "10800","5200"},
        {"13", "8", "韋小寶", "30", "19800", "15000", "2500"},
        {"12", "9", "楊過", "26", "9800", "5500"},
        {"11", "10", "小龍女", "21", "6600"},
        {"11", "11", "郭靖", "25", "7100"},
        {"12", "12", "黃蓉", "27", "9600", "4800"}
    };

    //PC      :21, model, display
    //NoteBook:22, model, price
    //Printer :23, type, name
    public static final String[][] EQUIPMENTS = {
        {},
        {"22", "聯想Y5", "6000"},
        {"21", "巨集碁 ", "AT7-N52"},
        {"21", "戴爾", "3800-R33"},
        {"23", "鐳射", "佳能 2900"},
        {"21", "華碩", "K30BD-21寸"},
        {"21", "海爾", "18-511X 19"},
        {"23", "針式", "愛普生20K"},
        {"22", "惠普m6", "5800"},
        {"21", "聯想", "ThinkCentre"},
        {"21", "華碩","KBD-A54M5 "},
        {"22", "惠普m6", "5800"}
    };
}</span>

TSUtility.java
<span style="font-size:18px;">public class TSUtility {
    private static Scanner scanner = new Scanner(System.in);

	public static char readMenuSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false);
            c = str.charAt(0);
            if (c != '1' && c != '2' &&
                c != '3' && c != '4') {
                System.out.print("選擇錯誤,請重新輸入:");
            } else break;
        }
        return c;
    }

    public static void readReturn() {
        System.out.print("按回車鍵繼續...");
        readKeyBoard(100, true);
    }

    public static int readInt() {
        int n;
        for (; ; ) {
            String str = readKeyBoard(2, false);
            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("數字輸入錯誤,請重新輸入:");
            }
        }
        return n;
    }

    public static char readConfirmSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false).toUpperCase();
            c = str.charAt(0);
            if (c == 'Y' || c == 'N') {
                break;
            } else {
                System.out.print("選擇錯誤,請重新輸入:");
            }
        }
        return c;
    }

    private static String readKeyBoard(int limit, boolean blankReturn) {
        String line = "";

        while (scanner.hasNextLine()) {
            line = scanner.nextLine();
            if (line.length() == 0) {
                if (blankReturn) return line;
                else continue;
            }

            if (line.length() < 1 || line.length() > limit) {
                System.out.print("輸入長度(不大於" + limit + ")錯誤,請重新輸入:");
                continue;
            }
            break;
        }

        return line;
    }
}</span>

參考實現程式碼:

首先完成各個包以及類的建立,如下圖:

其中各個檔案內的程式碼參考如下:

com.atguigu.team.domain的設計

Employee.java

<span style="font-size:18px;">package com.atguigu.team.domain;

public class Employee {
	
	private int id;
	private String name;
	private int age;
	private double salary;
	
	public Employee() {}
	
	public Employee(int id, String name, int age, double salary) {
		this.id = id;
		this.name = name;
		this.age = age;
		this.salary = salary;
	}
	
	public int getId() {
		return id;
	}
	
	public void setId(int id) {
		this.id = id;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public double getSalary() {
		return salary;
	}
	
	public void setSalary(double salary) {
		this.salary = salary;
	}
	
	public String say() {
		return id + "\t" + name + "\t" + age + "\t" + (int)salary;
	}

	@Override
	public String toString() {
		return say();
	}
	
}
</span>

Programmer.java
<span style="font-size:18px;">package com.atguigu.team.domain;

import com.atguigu.team.service.Status;

public class Programmer extends Employee {
	
	private int memberid;
	private Status status;//狀態
	private Equipment equipment;//關聯的物件,某種裝置

	public Programmer() {}
	
	public Programmer(int id, String name, int age, double salary,int memberid, Status status,Equipment equipment) {
		super(id, name, age, salary);
		this.memberid = memberid;
		this.status = status;
		this.equipment = equipment;
	}

	public int getMemberid() {
		return memberid;
	}

	public void setMemberid(int memberid) {
		this.memberid = memberid;
	}

	public Status getStatus() {
		return status;
	}

	public void setStatus(Status status) {
		this.status = status;
	}

	public Equipment getEquipment() {
		return equipment;
	}

	public void setEquipment(Equipment equipment) {
		this.equipment = equipment;
	}

	@Override
	public String toString() {
		return super.toString() + "\t程式設計師\t" + status + "\t\t\t" + equipment;
	}
	
	public String toString2() {
		return memberid + "/" + say() + "\t程式設計師";
	}
}
</span>

Designer.java
<span style="font-size:18px;">package com.atguigu.team.domain;

import com.atguigu.team.service.Status;

public class Designer extends Programmer {
	
	private double bonus;
	
	public Designer() {}
	
	public Designer(int id, String name, int age, double salary,int memberid, Status status,Equipment equipment, double bonus) {
		super(id, name, age, salary, memberid, status, equipment);
		this.bonus = bonus;
	}

	public double getBonus() {
		return bonus;
	}

	public void setBonus(double bonus) {
		this.bonus = bonus;
	}

	@Override
	public String toString() {
		return say() + "\t" + "設計師" + "\t" + getStatus() + "\t" + (int)bonus + "\t\t" + getEquipment();
	}
	
	public String toString2() {
		return getMemberid() + "/" + say() + "\t設計師" + "\t" + (int)bonus;
	}
}
</span>

Architect.java
<span style="font-size:18px;">package com.atguigu.team.domain;

import com.atguigu.team.service.Status;

public class Architect extends Designer {

	private int stock;
	
	public Architect() {}
	
	public Architect(int id, String name, int age, double salary,int memberid, Status status,Equipment equipment, double bonus,int stock) {
		super(id, name, age, salary, memberid, status, equipment, bonus);
		this.stock = stock;
	}

	public int getStock() {
		return stock;
	}

	public void setStock(int stock) {
		this.stock = stock;
	}

	@Override
	public String toString() {
		return super.say() + "\t" + "架構師" + "\t" + getStatus() + "\t" + (int)getBonus() + "\t" + stock + "\t" + getEquipment();
	}
	
	public String toString2() {
		return getMemberid() + "/" + say() + "\t架構師" + "\t" + (int)getBonus() + "\t" + stock;
	}
}
</span>

Equipment.java(介面)
<span style="font-size:18px;">package com.atguigu.team.domain;

public interface Equipment {
	
	public String getDescription();
}
</span>

PC.java
<span style="font-size:18px;">package com.atguigu.team.domain;

public class PC implements Equipment{
	
	private String model;
	private String display;
	
	public PC() {}
	
	public PC(String model, String display) {
		this.model = model;
		this.display = display;
	}

	public String getModel() {
		return model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public String getDisplay() {
		return display;
	}

	public void setDisplay(String display) {
		this.display = display;
	}

	@Override
	public String toString() {
		return  model + "(" + display + ")";
	}

	@Override
	public String getDescription() {
		return toString();
	}

	
}
</span>

NoteBook.java
<span style="font-size:18px;">package com.atguigu.team.domain;

public class NoteBook implements Equipment {

	private String model;
	private double price;
	
	public NoteBook() {}
	
	public NoteBook(String model, double price) {
		this.model = model;
		this.price = price;
	}
	
	public String getModel() {
		return model;
	}

	public void setModel(String model) {
		this.model = model;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return model + "(" + price + ")";
	}

	@Override
	public String getDescription() {
		return toString();
	}

}
</span>

Printer.java
<span style="font-size:18px;">package com.atguigu.team.domain;

public class Printer implements Equipment {

	private String type;
	private String name;
	
	public Printer() {
	}
	
	public Printer(String type, String name) {
		this.type = type;
		this.name = name;
	}

	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return type + "(" + name + ")";
	}

	@Override
	public String getDescription() {
		return toString();
	}

}
</span>

com.atguigu.team.service的設計

Data.java

<span style="font-size:18px;">package com.atguigu.team.service;

public class Data {
    public static final int EMPLOYEE = 10;
    public static final int PROGRAMMER = 11;
    public static final int DESIGNER = 12;
    public static final int ARCHITECT = 13;

    public static final int PC = 21;
    public static final int NOTEBOOK = 22;
    public static final int PRINTER = 23;

    //Employee  :  10, id, name, age, salary
    //Programmer:  11, id, name, age, salary
    //Designer  :  12, id, name, age, salary, bonus
    //Architect :  13, id, name, age, salary, bonus, stock
    public static final String[][] EMPLOYEES = {
        {"10", "1", "段譽", "22", "3000"},
        {"13", "2", "令狐沖", "32", "18000", "15000", "2000"},
        {"11", "3", "任我行", "23", "7000"},
        {"11", "4", "張三丰", "24", "7300"},
        {"12", "5", "周芷若", "28", "10000", "5000"},
        {"11", "6", "趙敏", "22", "6800"},
        {"12", "7", "張無忌", "29", "10800","5200"},
        {"13", "8", "韋小寶", "30", "19800", "15000", "2500"},
        {"12", "9", "楊過", "26", "9800", "5500"},
        {"11", "10", "小龍女", "21", "6600"},
        {"11", "11", "郭靖", "25", "7100"},
        {"12", "12", "黃蓉", "27", "9600", "4800"}
    };

    //PC      :21, model, display
    //NoteBook:22, model, price
    //Printer :23, type, name
    public static final String[][] EQUIPMENTS = {
        {},
        {"22", "聯想Y5", "6000"},
        {"21", "巨集碁 ", "AT7-N52"},
        {"21", "戴爾", "3800-R33"},
        {"23", "鐳射", "佳能 2900"},
        {"21", "華碩", "K30BD-21寸"},
        {"21", "海爾", "18-511X 19"},
        {"23", "針式", "愛普生20K"},
        {"22", "惠普m6", "5800"},
        {"21", "聯想", "ThinkCentre"},
        {"21", "華碩","KBD-A54M5 "},
        {"22", "惠普m6", "5800"}
    };
}
</span>

Status.java
<span style="font-size:18px;">package com.atguigu.team.service;

public enum Status {
    FREE, BUSY, VOCATION
}
</span>

TeamExcetion.java
<span style="font-size:18px;">package com.atguigu.team.service;

@SuppressWarnings("serial")
public class TeamException extends Exception{

	public TeamException(String message) {
		super(message);
	}
	
	public TeamException(Exception cause) {
		super(cause);
	}
}
</span>

CompanyService.java
<span style="font-size:18px;">package com.atguigu.team.service;

import com.atguigu.team.domain.Architect;
import com.atguigu.team.domain.Designer;
import com.atguigu.team.domain.Employee;
import com.atguigu.team.domain.Equipment;
import com.atguigu.team.domain.NoteBook;
import com.atguigu.team.domain.PC;
import com.atguigu.team.domain.Printer;
import com.atguigu.team.domain.Programmer;

public class CompanyService {
	
	private Employee[] employees;
	
	public CompanyService() {
		// 先處理所有的裝置物件
		// 建立一個裝置陣列
		Equipment[] eqs = new Equipment[Data.EQUIPMENTS.length];
		for (int i = 2; i < Data.EQUIPMENTS.length; i++) {
			// 獲取子陣列
			String[] child = Data.EQUIPMENTS[i];
			// 獲取識別碼, 並轉換成整數
			int code = Integer.parseInt(child[0]);
			// 樣例資料: {"21", "巨集碁 ", "AT7-N52"},
			 // PC      :21, model, display
			if (code == Data.PC) {
				// 當前子陣列中的資料就可以整合成一個PC物件
				//public PC(String model, String display) {
				String model = child[1];
				String display = child[2];
				// 物件儲存在陣列中
				eqs[i] = new PC(model, display);
			} else if (code == Data.NOTEBOOK) {
				//樣例 : {"22", "聯想Y5", "6000"},
				//NoteBook:22, model, price
				// 當前子陣列中的資料就可以整合成一個NoteBook物件
				// public NoteBook(String model, double price) {
				String model = child[1];
				double price = Integer.parseInt(child[2]);
				// 物件儲存在陣列中
				eqs[i] = new NoteBook(model, price);
			} else if (code == Data.PRINTER) {
				//樣例 : {"23", "鐳射", "佳能 2900"},
				//Printer :23, type, name
				// 當前子陣列中的資料就可以整合成一個Printer物件
				// public Printer(String type, String name) {
				String type = child[1];
				String name = child[2];
				// 物件儲存在陣列中
				eqs[i] = new Printer(type, name);
			}
		}
		/* 測試用
		for (Equipment equipment : eqs) {
			System.out.println(equipment);
		}*/
		
		this.employees = new Employee[Data.EMPLOYEES.length];
		for (int i = 0; i < Data.EMPLOYEES.length; i++) {
			// 獲取子陣列
			String[] child = Data.EMPLOYEES[i];
			// 獲取識別碼, 轉成整數
			int code = Integer.parseInt(child[0]);
			int id = Integer.parseInt(child[1]);
			String name = child[2];
			int age = Integer.parseInt(child[3]);
			double salary = Integer.parseInt(child[4]);
			//樣例{"10", "1", "段譽", "22", "3000"},
			//Employee  :  10, id, name, age, salary
			if (code == Data.EMPLOYEE) {
				// 建立Employee物件
				//public Employee(int id, String name, int age, double salary) {
				//建立好物件後, 儲存在陣列中
				this.employees[i] = new Employee(id, name, age, salary);
			} else if (code == Data.PROGRAMMER) {
				//{"11", "3", "任我行", "23", "7000"},
				//Programmer:  11, id, name, age, salary
				/*public Programmer(  int id, 
									  String name, 
									  int age, 
									  double salary,
									  int memberId, 
									  Status status, 
									  Equipment equipment) {*/
				//裝置物件從上面的陣列中獲取, 只需要對應的元素即可
				//建立好物件後, 儲存在陣列中
				this.employees[i] = new Programmer(id,
												   name,
												   age,
												   salary,
												   0,
												   Status.FREE,
												   eqs[i]);
			} else if (code == Data.DESIGNER) {
				//{"12", "5", "周芷若", "28", "10000", "5000"},
				//Designer  :  12, id, name, age, salary, bonus
				/*
				public Designer(int id, 
								String name, 
								int age, 
								double salary, 
								int memberId,
								Status status, 
								Equipment equipment, 
								double bonus) {
				 */
				//裝置物件從上面的陣列中獲取, 只需要對應的元素即可
				double bonus = Integer.parseInt(child[5]);
				//建立好物件後, 儲存在陣列中
				this.employees[i] = new Designer(id, name, age, salary, 0, Status.FREE, eqs[i], bonus);
			} else if (code == Data.ARCHITECT) {
				//{"13", "2", "令狐沖", "32", "18000", "15000", "2000"},
				//Architect :  13, id, name, age, salary, bonus, stock
				/*
				public Architect(int id, 
								 String name, 
								 int age, 
								 double salary, 
								 int memberId,
								 Status status, 
								 Equipment equipment, 
								 double bonus, 
								 int stock) {
				*/
				//裝置物件從上面的陣列中獲取, 只需要對應的元素即可
				double bonus = Integer.parseInt(child[5]);
				int stock = Integer.parseInt(child[6]);
				//建立好物件後, 儲存在陣列中
				this.employees[i] = new Architect(id, name, age, salary, 0, Status.FREE, eqs[i], bonus, stock);
			}
		}
		
		//測試用
		/*
		for (int j = 0; j < employees.length; j++) {
			System.out.println(employees[j]);
		}*/
		
	}
	
	/**
	 * 獲取所有員工的儲存的陣列
	 * @return
	 */
	public Employee[] getAllEmployees() {
		/*
		Employee[] copy = new Employee[employees.length];
		for (int i = 0; i < copy.length; i++) {
			copy[i] = employees[i];
		}
		return copy;
		*/
		return employees;
	}
	
	/**
	 * 方法:獲取指定ID的員工物件。
	 * @param id 指定員工的ID
	 * @return 指定員工物件
	 * 異常:找不到指定的員工
	 */
	public Employee getEmployee(int id) throws TeamException {
		// 遍歷所有員工的陣列
		for (int i = 0; i < employees.length; i++) {
			// 如果某員工的ID屬性和引數id一樣,就返回這個員工物件
			if (employees[i].getId() == id) {
				return employees[i];
			}
		}
		// 如果沒有找到物件, 丟擲異常 throw 
		throw new TeamException("找不到指定ID[" + id + "]的員工");
	}
	
}
</span>


TeamService.java

<span style="font-size:18px;">package com.atguigu.team.service;

import com.atguigu.team.domain.Architect;
import com.atguigu.team.domain.Designer;
import com.atguigu.team.domain.Employee;
import com.atguigu.team.domain.Programmer;

public class TeamService {
	
	private static int counter = 1;
	
	public final int MAX_MEMBER = 6;
	private Programmer[] team = new Programmer[MAX_MEMBER];
	private int realCount = 0;
	
	/**
	 * 新增一個員工物件到團隊中
	 * @param emp
	 * @throws TeamException 因某種原因失敗
	 */
	public void addMember(Employee emp) throws TeamException {
		if (realCount == team.length) {
			throw new TeamException("成員已滿,無法新增");
		}
		if (!(emp instanceof Programmer)) {
			throw new TeamException("新增的成員不是開發人員"); // 提前錯誤返回
		}
		Programmer programmer = (Programmer)emp;
		if (programmer.getMemberId() != 0) {
			throw new TeamException("該員已是團隊成員");
		}
		if (programmer.getStatus() == Status.VOCATION) {
			throw new TeamException("該員正在休假,無法新增");
		}
		int architectCount = 0;
		int designerCount = 0;
		int programmerCount = 0;
		for (int i = 0; i < realCount; i++) {
			if (team[i] instanceof Architect) {
				architectCount++;
			} else if (team[i] instanceof Designer) {
				designerCount++;
			} else {
				programmerCount++;
			}
		}
		// 對將要新增的新成員的身份作一個判斷
		if (programmer instanceof Architect) {
			if (architectCount == 1) {
				throw new TeamException("團隊中只能有一名架構師");
			}
		} else if (programmer instanceof Designer) {
			if (designerCount == 2) {
				throw new TeamException("團隊中只能有兩名設計師");
			}
		} else {
			if (programmerCount == 3) {
				throw new TeamException("團隊中只能有三名程式設計師");
			}
		}
		
		programmer.setMemberId(counter++); // 為要新增的新成員賦予一個團隊ID號
		programmer.setStatus(Status.BUSY); // 修改物件的狀態為busy
		team[realCount++] = programmer;
	}
	
	/**
	 * 獲取所有團隊成員的陣列
	 * @return 完美陣列
	 */
	public Programmer[] getTeam() {
		// 建立一個臨時陣列
		Programmer[] tmp = new Programmer[realCount];
		// 挨個複製所有有效元素
		for (int i = 0; i < tmp.length; i++) {
			tmp[i] = team[i];
		}
		// 返回臨時陣列
		return tmp;
	}
	
	/**
	 * 刪除指定TID的團隊成員
	 * @param memberId
	 * @throws TeamException
	 */
	public void removeMember(int memberId) throws TeamException {
		// 先根據memberId定位要刪除的成員的下標
		int index = -1; // 先假定要刪除的TID成員的下標不存在
		for (int i = 0; i < realCount; i++) {
			if (team[i].getMemberId() == memberId) {
				index = i;
				break;
			}
		}
		if (index == -1) { // 檢索完成後, 再次檢測下標是否有效, 如果無效說明沒有找到
			throw new TeamException("要刪除的TID[" + memberId + "]的團隊成員未找到!");
		}
		// 在覆蓋要刪除的物件前進行物件的資料修改
		team[index].setMemberId(0); // 剝奪ID
		team[index].setStatus(Status.FREE); // 還原狀態
		
		// 從要刪除的下標開始,依次把右邊的元素移到左邊
		for (int j = index; j < realCount - 1; j++) {
			team[j] = team[j + 1];
		}
		// 把最後一個有效元素置為空洞
		// 調整計數器
		team[--realCount] = null;
	}
	
}
</span>

com.atguigu.team.view的設計

TSUtility.java

<span style="font-size:18px;">package com.atguigu.team.view;

import java.util.*;

public class TSUtility {
    private static Scanner scanner = new Scanner(System.in);

	public static char readMenuSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false);
            c = str.charAt(0);
            if (c != '1' && c != '2' &&
                c != '3' && c != '4') {
                System.out.print("選擇錯誤,請重新輸入:");
            } else break;
        }
        return c;
    }

    public static void readReturn() {
        System.out.print("按回車鍵繼續...");
        readKeyBoard(100, true);
    }

    public static int readInt() {
        int n;
        for (; ; ) {
            String str = readKeyBoard(2, false);
            try {
                n = Integer.parseInt(str);
                break;
            } catch (NumberFormatException e) {
                System.out.print("數字輸入錯誤,請重新輸入:");
            }
        }
        return n;
    }

    public static char readConfirmSelection() {
        char c;
        for (; ; ) {
            String str = readKeyBoard(1, false).toUpperCase();
            c = str.charAt(0);
            if (c == 'Y' || c == 'N') {
                break;
            } else {
                System.out.print("選擇錯誤,請重新輸入:");
            }
        }
        return c;
    }

    private static String readKeyBoard(int limit, boolean blankReturn) {
        String line = "";

        while (scanner.hasNextLine()) {
            line = scanner.nextLine();
            if (line.length() == 0) {
                if (blankReturn) return line;
                else continue;
            }

            if (line.length() < 1 || line.length() > limit) {
                System.out.print("輸入長度(不大於" + limit + ")錯誤,請重新輸入:");
                continue;
            }
            break;
        }

        return line;
    }
}
</span>

TeamView.java
<span style="font-size:18px;">package com.atguigu.team.view;

import com.atguigu.team.domain.Employee;
import com.atguigu.team.domain.Programmer;
import com.atguigu.team.service.CompanyService;
import com.atguigu.team.service.TeamException;
import com.atguigu.team.service.TeamService;

public class TeamView {
	
	/**
	 * 負責處理和公司員工相關的業務
	 */
	private CompanyService companyService = new CompanyService();
	/**
	 * 負責處理和團隊相關的業務
	 */
	private TeamService teamService = new TeamService();
	
	/**
	 * 進入主選單方法, 相當於入口方法
	 */
	public void enterMainMenu() {
		boolean loopFlag = true;
		while (loopFlag) {
			listAllEmployees();
			System.out.print("1-團隊列表  2-新增團隊成員  3-刪除團隊成員 4-退出   請選擇(1-4) : ");
			// 獲取使用者的鍵盤輸入
			char choice = TSUtility.readMenuSelection();
			// 對使用者輸入作出分支 
			switch (choice) {
				// 如果是'1' 呼叫 listTeam()
				case '1' : listTeam(); break;
				// 如果是'2' 呼叫 addMember()
				case '2' : addMember(); break;
				// 如果是'3' 呼叫 deleteMember()
				case '3' : deleteMember(); break;
				// 如果是'4' 設定迴圈變數為false
				case '4' : loopFlag = false; break;
			}
		}
	}
	
	/**
	 * 列出公司所有員工
	 */
	private void listAllEmployees() {
		System.out.println("-------------------------------------開發團隊排程軟體--------------------------------------");
		System.out.println();
		System.out.println("ID\t姓名\t年齡\t工資\t職位\t狀態\t獎金\t股票\t領用裝置");
		Employee[] allEmps = companyService.getAllEmployees();
		for (int i = 0; i < allEmps.length; i++) {
			System.out.println(allEmps[i]);
		}
		System.out.println("---------------------------------------------------------------------------------------------------");
	}
	
	/**
	 * 新增成員到team中
	 * @throws  
	 */
	private void addMember() {
		System.out.println("---------------------新增成員---------------------");
		System.out.print("請輸入要新增的員工ID : ");
		// 獲取使用者從鍵盤輸入的ID
		int id = TSUtility.readInt();
		try {
			// 從companyService中獲取物件,依據是ID號
			Employee employee = companyService.getEmployee(id);
			// 把獲取到的物件新增到teamService中, 呼叫方法addMember(Employee emp)
			teamService.addMember(employee);
			System.out.println("新增成功!");
		} catch (TeamException e) {
			System.out.println("新增失敗, 原因 : " + e.getMessage());
		}
		// 呼叫工具類的readReturn()
		TSUtility.readReturn();
	}
	
	/**
	 * 從團隊中刪除成員
	 */
	private void deleteMember() {
		System.out.println("---------------------刪除成員---------------------");
		System.out.print("請輸入要刪除員工的TID : ");
		int id = TSUtility.readInt();
		System.out.print("確認是否刪除(Y/N) :");
		char confirm = TSUtility.readConfirmSelection();
		if (confirm == 'Y') {
			try {
				teamService.removeMember(id);
				System.out.println("刪除成功!");
			} catch (TeamException e) {
				System.out.println("刪除失敗, 原因 : " + e.getMessage());
			}
			TSUtility.readReturn();
		}
	}
	
	/**
	 * 列出團隊成員
	 */
	private void listTeam() {
		System.out.println("--------------------團隊成員列表---------------------");
		System.out.println();
		System.out.println("TID/ID\t姓名\t年齡\t工資\t職位\t獎金\t股票");
		Programmer[] team = teamService.getTeam();
		for (Programmer programmer : team) {
			System.out.println(programmer.toString2());
		}
		System.out.println("-----------------------------------------------------");
	}
}
</span>

com.atguigu.team.main的設計

TeamMain.java

<span style="font-size:18px;">package com.atguigu.team.main;

import com.atguigu.team.domain.Architect;
import com.atguigu.team.domain.Designer;
import com.atguigu.team.domain.Employee;
import com.atguigu.team.domain.Equipment;
import com.atguigu.team.domain.NoteBook;
import com.atguigu.team.domain.PC;
import com.atguigu.team.domain.Printer;
import com.atguigu.team.domain.Programmer;
import com.atguigu.team.service.CompanyService;
import com.atguigu.team.service.Status;
import com.atguigu.team.service.TeamException;
import com.atguigu.team.service.TeamService;
import com.atguigu.team.view.TeamView;

public class TeamMain {
	
	public static void main(String[] args) {
		new TeamView().enterMainMenu();
	}
	
	public static void main1(String[] args) {
		CompanyService companyService = new CompanyService();
		Employee[] emps = companyService.getAllEmployees();
		for (int i = 0; i < emps.length; i++) {
			System.out.println(emps[i]);
		}
		System.out.println("-------------------------");
		Employee emp;
		try {
			emp = companyService.getEmployee(90);
			System.out.println(emp);
		} catch (TeamException e) {
			e.printStackTrace();
		}
	}
	
	public static void main0(String[] args) {
		Employee emp1 = new Employee(1, "張一", 10, 1000);
		//System.out.println(emp1);
		/*
		public Programmer(int id, 
						  String name, 
						  int age, 
						  double salary,
						  int memberId, 
						  Status status, 
						  Equipment equipment) {
		*/
		Equipment eq1 = new PC("T440", "聯想14寸");
		Employee emp2 = new Programmer(2, "張二", 20, 2000, 0, Status.FREE, eq1);
		//System.out.println(emp2);
		
		/*
		public Designer(int id, 
						String name, 
						int age, 
						double salary, 
						int memberId,
						Status status, 
						Equipment equipment, 
						double bonus) { 
		 */
		Equipment eq2 = new NoteBook("MBP13", 10000);
		Employee emp3 = new Designer(3, "張三", 30, 3000, 0, Status.FREE, eq2, 30000);
		//System.out.println(emp3);
		
		/*
		public Architect(int id, 
						 String name, 
						 int age, 
						 double salary, 
						 int memberId,
						 Status status, 
						 Equipment equipment, 
						 double bonus, 
						 int stock) { 
		 */
		Equipment eq3 = new Printer("鐳射", "HP1020");
		Employee emp4 = new Architect(4, "張四", 40, 4000, 0, Status.VOCATION, eq3, 40000, 400000);
		//System.out.println(emp4);
		
		TeamService teamService = new TeamService();
		try {
			teamService.addMember(emp1);
		} catch (TeamException e) {
			System.out.println(e);
		}
		try {
			teamService.addMember(emp2);
		} catch (TeamException e) {
			System.out.println(e);
		}
		try {
			teamService.addMember(emp3);
		} catch (TeamException e) {
			System.out.println(e);
		}
		try {
			teamService.addMember(emp4);
		} catch (TeamException e) {
			System.out.println(e);
		}
		Programmer[] tmp = teamService.getTeam();
		for (int i = 0; i < tmp.length; i++) {
			System.out.println(tmp[i]);
		}
		System.out.println("------------------------------");
		try {
			teamService.removeMember(2);// 張二, 張三, 張四
		} catch (TeamException e) {
			System.out.println(e);
		} 
		// 刪除完成後,再次遍歷
		tmp = teamService.getTeam();
		for (int i = 0; i < tmp.length; i++) {
			System.out.println(tmp[i]);
		}
		System.out.println("------------------------------");
	}
}
</span>

執行結果如下:




按照以上的方法新增3、4、6、10號員工,然而新增到10號員工時出現如下介面


此時團隊中的成員如圖:


此時新增8號員工,出現如下介面:


接著在新增5、9、12號員工,出現如下介面:


接著刪除3號員工


此時團隊成員如下:


此時我們插入7號員工,出現如下介面:


到這裡所有功能均已實現,小專案完成。