1.模拟实现一个基于文本界面的《开发团队调度软件》
2.熟悉Java面向对象的高级特性,进一步掌握编程技巧和调试技巧
3.主要涉及以下知识点:
类的继承性和多态性
对象的值传递、接口
static和final修饰符
特殊类的使用:包装类、抽象类、内部类
异常处理
4.界面显示如下:
-------------------------------------开发团队调度软件--------------------------------------
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):
5.代码如下:
/*这里是员工类*/
public class Employee {
//属性
private int id;//人员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;
}
/*getter setter方法*/
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;
}
//1 马云 22 3000.0
public String basicInfor(){
return getId()+"\t"+getName()+"\t"+getAge()+"\t"+getSalary();
}
@Override
public String toString() {
return basicInfor();
}
}
/*程序员类*/
public class Programmer extends Employee {
/*属性*/
private int memberId;//成员id
private Status status=Status.FREE;//状态
private Equipment equipment;//员工所拥有的设备
/*构造器*/
public Programmer() {
}
public Programmer(int id, String name, int age, double salary, Equipment equipment) {
super(id, name, age, salary);
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;
}
//3 李彦宏 23 7000.0 程序员 FREE 戴尔(NEC17寸)
@Override
public String toString() {
return basicInfor()+"\t"+"程序员\t"+getStatus()+"\t\t\t\t\t"+getEquipment().getDescription();
}
//2/3 李彦宏 23 7000.0 程序员
public String getTeamInfor(){
return getBasicTeamInfor()+"\t程序员";
}
public String getBasicTeamInfor(){
return getMemberId()+"/"+getId()+"\t"+getName()+"\t"+getAge()+"\t"+getSalary();
}
}
/*这里是设计师类*/
public class Designer extends Programmer {
/*属性*/
private double bonus;//奖金
/*构造器*/
public Designer() {
}
public Designer(int id, String name, int age, double salary, Equipment equipment, double bonus) {
super(id, name, age, salary,equipment);
this.bonus = bonus;
}
/*getter setter方法*/
public double getBonus() {
return bonus;
}
public void setBonus(double bonus) {
this.bonus = bonus;
}
//5 雷军 28 10000.0 设计师 FREE 5000.0 佳能 2900(激光)
@Override
public String toString() {
return basicInfor()+"\t"+"设计师\t"+getStatus()+"\t"+getBonus()+"\t\t\t"+getEquipment().getDescription();
}
//3/5 雷军 28 10000.0 设计师 5000.0
@Override
public String getTeamInfor() {
return getBasicTeamInfor()+"\t设计师"+"\t"+getBonus();
}
}
/*这里是架构师类*/
public class Architect extends Designer {
/*属性*/
private int stock;//股票
/*构造器*/
public Architect() {
}
public Architect(int id, String name, int age, double salary,Equipment equipment,double bonus, int stock) {
super(id, name, age, salary,equipment,bonus);
this.stock = stock;
}
/*getter setter方法*/
public int getStock() {
return stock;
}
public void setStock(int stock) {
this.stock = stock;
}
//2 马化腾 32 18000.0 架构师 FREE 15000.0 2000 联想T4(6000.0)
@Override
public String toString() {
return basicInfor()+"\t"+"架构师\t"+ getStatus()+"\t"+getBonus()+"\t"+getStock()+"\t"+getEquipment().getDescription();
}
//1/2 马化腾 32 18000.0 架构师 15000.0 2000
@Override
public String getTeamInfor() {
return getBasicTeamInfor()+"\t架构师"+"\t"+getBonus()+"\t"+getStock();
}
}
/*这是设备的接口*/
public interface Equipment {
String getDescription();
}
/*这是笔记本类*/
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;
}
@Override
public String getDescription() {
return model+"("+price+")";
}
}
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;
}
@Override
public String getDescription() {
return model+"("+display+")";
}
}
public class Printer implements Equipment {
//属性
private String name;//名称
private String type;//机器类型
//构造器
public Printer() {
}
public Printer(String name, String type) {
this.name = name;
this.type = type;
}
@Override
public String getDescription() {
return name+"("+type+")";
}
}
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"}
};
//如下的EQUIPMENTS数组与上面的EMPLOYEES数组元素一一对应
//PC :21, model, display
//NoteBook:22, model, price
//Printer :23, name, type
public static final String[][] EQUIPMENTS = {
{},
{"22", "联想T4", "6000"},
{"21", "戴尔", "NEC17寸"},
{"21", "戴尔", "三星 17寸"},
{"23", "佳能 2900", "激光"},
{"21", "华硕", "三星 17寸"},
{"21", "华硕", "三星 17寸"},
{"23", "爱普生20K", "针式"},
{"22", "惠普m6", "5800"},
{"21", "戴尔", "NEC 17寸"},
{"21", "华硕","三星 17寸"},
{"22", "惠普m6", "5800"}
};
}
/**
* @Auther:ThroneW
* @Date:2020/11/20-11-20-19:40
* @Description: 负责将Data中的数据封装到Employee[]数组中,同时提供相关操作
* @version:1.0
*/
public class NameListService {
/*属性*/
private Employee[] employees;
/*构造器
* 根据项目提供的Data类构建相应大小的employees数组
再根据Data类中的数据构建不同的对象,包括Employee、Programmer、Designer和Architect对象,
以及相关联的Equipment子类的对象
将对象存于数组中
*
* */
public NameListService() {
employees =new Employee[EMPLOYEES.length];
for (int i = 0; i < employees.length; i++) {
int key=Integer.parseInt(EMPLOYEES[i][0]);
int id=Integer.parseInt(EMPLOYEES[i][1]);
String name=EMPLOYEES[i][2];
int age=Integer.parseInt(EMPLOYEES[i][3]);
double salary=Double.parseDouble(EMPLOYEES[i][4]);
Equipment equipment=null;
double bonus=0;
switch (key){
case EMPLOYEE:
employees[i]=new Employee(id,name,age,salary);
break;
case PROGRAMMER:
equipment=createEquipment(i);
employees[i]=new Programmer(id,name,age,salary,equipment);
break;
case DESIGNER:
equipment=createEquipment(i);
bonus=Double.parseDouble(EMPLOYEES[i][5]);
employees[i]=new Designer(id,name,age,salary,equipment,bonus);
break;
case ARCHITECT:
equipment=createEquipment(i);
bonus=Double.parseDouble(EMPLOYEES[i][5]);
int stock=Integer.parseInt(EMPLOYEES[i][6]);
employees[i]=new Architect(id,name,age,salary,equipment,bonus,stock);
break;
}
}
}
/*
* //如下的EQUIPMENTS数组与上面的EMPLOYEES数组元素一一对应
//PC :21, model, display
//NoteBook:22, model, price
//Printer :23, name, type
*
* */
/**
* 创建一个设备的方法
* @param i 根据不同的序号,拿到不同类型的设备
* @return
*/
private Equipment createEquipment(int i) {
int key=Integer.parseInt(EQUIPMENTS[i][0]);
String model=EQUIPMENTS[i][1];
Equipment equipment=null;
switch (key){
case PC:
String display=EQUIPMENTS[i][2];
equipment=new PC(model,display);
break;
case NOTEBOOK:
double price=Double.parseDouble(EQUIPMENTS[i][2]);
equipment=new NoteBook(model,price);
break;
case PRINTER:
String name=EQUIPMENTS[i][1];
String type=EQUIPMENTS[i][2];
equipment=new Printer(name,type);
break;
}
return equipment;
}
/**
* 获取当前所有员工
* @return 包含所有员工对象的数组
*/
public Employee[] getAllEmployees(){
return employees;
}
/**
*获取指定ID的员工对象
* @param id 指定员工的ID
* @return 指定员工对象
* @throws TeamException 找不到指定的员工
*/
public Employee getEmployee(int id)throws TeamException{
Employee employee=null;
for (int i = 0; i < employees.length; i++) {
if (id==employees[i].getId()){
employee=employees[i];
return employee;
}
}
throw new TeamException("找不到指定的員工");
}
public static void main(String[] args) {
NameListService nameListService=new NameListService();
/*for (int i = 0; i < nameListService.employees.length; i++) {
System.out.println(nameListService.employees[i]);
}*/
try {
Employee employee = nameListService.getEmployee(2);
System.out.println(employee);
} catch (TeamException e) {
System.out.println(e.getMessage());
}
}
}
public class Status {
private final String NAME;
/*1.构造器私有化*/
private Status(String name){
this.NAME=name;
}
/*2.创建一个静态类的对象*/
public static final Status FREE=new Status("FREE");
public static final Status VOCATION=new Status("VOCATION");
public static final Status BUSY=new Status("BUSY");
/*3.通过方法获取对象*/
public String getNAME(){
return NAME;
}
@Override
public String toString() {
return NAME;
}
}
public class TeamException extends Exception {
static final long serialVersionUID = -338724229948L;
public TeamException(String msg){
super(msg);
}
}
/**
* @Auther:ThroneW
* @Date:2020/11/21-11-21-19:09
* @Description:关于开发团队成员的管理:添加、删除等。
* @version:1.0
*/
public class TeamService {
/*属性*/
private static int counter = 1;//用来为开发团队新增成员自动生成团队中的唯一ID
private final int MAX_MEMBER = 5;//表示开发团队最大的成员人数
private Programmer[] team = new Programmer[MAX_MEMBER];//用来保存当前团队中的各成员对象
private int total = 0;//记录团队中实际的人员数
/*添加团队成员的第二种写法,要引入三个变量*/
private int archNum = 0;
private int desiNum = 0;
private int proNum = 0;
/*构造器*/
/*方法*/
/**
* 返回当前团队的所有对象
*
* @return 包含所有成员对象的数组,数组大小与成员人数一致
*/
public Programmer[] getTeam() throws TeamException {
if (total <= 0) {
throw new TeamException("团队中没有成员!");
}
Programmer[] team = new Programmer[total];
for (int i = 0; i < total; i++) {
team[i] = this.team[i];
}
return team;
}
/**
* 向团队中添加成员
*
* @param e 待添加成员的对象
* @throws TeamException 添加失败, TeamException中包含了失败原因
*/
public void addMember(Employee e) throws TeamException {
//成员已满,无法添加
if (total >= MAX_MEMBER) {
throw new TeamException("成员已满,无法添加");
}
//该成员不是开发人员,无法添加
if (!(e instanceof Programmer)) {
throw new TeamException("该成员不是开发人员,无法添加");
}
//该员工已在本开发团队中
if (isExit(e)) {
throw new TeamException("该员工已在本开发团队中");
}
Programmer p = (Programmer) e;
//该员工已是某团队成员
//该员正在休假,无法添加
if ("BUSY".equals(p.getStatus())) {
throw new TeamException("该员工已是某团队成员");
} else if ("VOCATION".equals(p.getStatus())) {
throw new TeamException("该员正在休假,无法添加");
}
//团队中至多只能有一名架构师
//团队中至多只能有两名设计师
//团队中至多只能有三名程序员
//先统计团队中各个人员的数量
/*int proNum = 0, desiNum = 0, archNum = 0;
for (int i = 0; i < total; i++) {
if (team[i] instanceof Architect) {
archNum++;
} else if (team[i] instanceof Designer) {
desiNum++;
} else if (team[i] instanceof Programmer) {
proNum++;
}
}
if (p instanceof Architect) {
if (archNum>=1)
throw new TeamException("团队中至多只能有一名架构师");
}else if (p instanceof Designer) {
if (desiNum>=2)
throw new TeamException("团队中至多只能有两名设计师");
}else if (p instanceof Programmer) {
if (proNum>=3)
throw new TeamException("团队中至多只能有三名程序员");
}*/
//第二种写法,引入三个属性,避免了一次循环。程序的时间复杂度减小,但是空间复杂度增加
if (p instanceof Architect){
archNum++;
}else if (p instanceof Designer){
desiNum++;
}else if (p instanceof Programmer){
proNum++;
}
if (archNum>1){
throw new TeamException("团队中至多只能有一名架构师");
}
if (desiNum>2){
throw new TeamException("团队中至多只能有两名设计师");
}
if (proNum>3){
throw new TeamException("团队中至多只能有三名程序员");
}
p.setStatus(Status.BUSY);
p.setMemberId(counter++);
team[total++] = p;
}
/**
* 判断该员工是否在团队中
*
* @return 在团队中返回true,否则返回false
*/
private boolean isExit(Employee employee) {
for (int i = 0; i < total; i++) {
if (employee.getId() == team[i].getId()) {
return true;
}
}
return false;
}
/**
* 从团队中删除成员
*
* @param memberId 待删除成员的memberId
* @throws TeamException 找不到指定memberId的员工,删除失败
*/
public void removeMember(int memberId) throws TeamException {
//遍历团队数组,看是否有指定的员工
int position = -1;
//先找到指定的员工
for (int i = 0; i < total; i++) {
if (team[i] != null && team[i].getMemberId() == memberId) {
position = i;
break;
}
}
//如果找到员工,就可以从那个位置开始删除
if (position != -1) {
for (int j = position; j < total - 1; j++) {
team[j] = team[j + 1];
}
//第一种写法时,这段代码可以省略
if (team[position] instanceof Architect){
archNum--;
}else if (team[position] instanceof Designer){
desiNum--;
}else if (team[position] instanceof Programmer){
proNum--;
}
team[position].setStatus(Status.FREE);
team[--total] = null;
} else {
throw new TeamException("找不到指定memberId的员工,删除失败");
}
}
}
/**
* @Auther:ThroneW
* @Date:2020/11/22-11-22-20:00
* @Description:
* @version:1.0
*/
public class TeamView {
//属性
//供类中的方法使用
private NameListService listSvc=new NameListService();
private TeamService teamSvc=new TeamService();
/**
* 主界面显示及控制方法
*/
public void enterMainMenu(){
boolean loopFlag=true;
boolean isLoopCompanyInfor=true;//是否循环现实公司员工信息。
while (loopFlag){
if (isLoopCompanyInfor){
System.out.println("-------------------------------开发团队调度软件--------------------------------\n");
System.out.println("ID\t姓名\t年龄\t工资\t职位\t状态\t奖金\t股票\t领用设备");
listAllEmployees();
System.out.println("-------------------------------------------------------------------------------");
}
System.out.print("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出 请选择(1-4):");
char select = TSUtility.readMenuSelection();
switch (select){
case '1':
getTeam();
isLoopCompanyInfor=false;
break;
case '2':
addMember();
isLoopCompanyInfor=true;
break;
case '3':
deleteMember();
isLoopCompanyInfor=true;
break;
case '4':
System.out.print("确认是否退出(Y/N):");
char confirm = TSUtility.readConfirmSelection();
if (confirm=='Y'){
loopFlag=false;
}
break;
}
}
}
/**
* 以表格形式列出公司所有成员
*/
private void listAllEmployees(){
Employee[] allEmployees = listSvc.getAllEmployees();
for (int i = 0; i < allEmployees.length; i++) {
System.out.println(allEmployees[i]);
}
}
/**
* 显示团队成员列表操作
*/
private void getTeam(){
//获取团队成员
System.out.println("--------------------团队成员列表---------------------\n");
Programmer[] team=null;
try {
team = teamSvc.getTeam();
System.out.println("TID/ID\t姓名\t年龄\t工资\t职位\t奖金\t股票");
for (int i = 0; i < team.length; i++) {
System.out.println(team[i].getTeamInfor());
}
} catch (TeamException e) {
System.out.println(e.getMessage());
}
System.out.println("-----------------------------------------------------");
}
/**
*实现添加成员操作
*/
private void addMember(){
System.out.println("---------------------添加成员---------------------");
System.out.print("请输入要添加的员工ID:");
int id = TSUtility.readInt();
try {
Employee employee = listSvc.getEmployee(id);
teamSvc.addMember(employee);
System.out.println("添加成功!");
TSUtility.readReturn();
} catch (TeamException e) {
System.out.println(e.getMessage());
}
System.out.println("-----------------------------------------------------");
}
/**
* 实现删除成员操作
*/
private void deleteMember(){
System.out.println("---------------------删除成员---------------------");
System.out.print("请输入要删除员工的TID:");
int id = TSUtility.readInt();
System.out.print("确认是否删除(Y/N):");
char confirm = TSUtility.readConfirmSelection();
if ('Y'==confirm){
try {
teamSvc.removeMember(id);
System.out.println("删除成功!");
TSUtility.readReturn();
} catch (TeamException e) {
System.out.println(e.getMessage());
}
System.out.println("-----------------------------------------------------");
}
}
public static void main(String[] args) {
TeamView tv=new TeamView();
tv.enterMainMenu();
}
}
/**
*
* @Description 项目中提供了TSUtility.java类,可用来方便地实现键盘访问。
* @author shkstart Email:[email protected]
* @version
* @date 2019年2月12日上午12:02:58
*
*/
public class TSUtility {
private static Scanner scanner = new Scanner(System.in);
/**
*
* @Description 该方法读取键盘,如果用户键入’1’-’4’中的任意字符,则方法返回。返回值为用户键入字符。
* @author shkstart
* @date 2019年2月12日上午12:03:30
* @return
*/
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;
}
/**
*
* @Description 该方法提示并等待,直到用户按回车键后返回。
* @author shkstart
* @date 2019年2月12日上午12:03:50
*/
public static void readReturn() {
System.out.print("按回车键继续...");
readKeyBoard(100, true);
}
/**
*
* @Description 该方法从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
* @author shkstart
* @date 2019年2月12日上午12:04:04
* @return
*/
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;
}
/**
*
* @Description 从键盘读取‘Y’或’N’,并将其作为方法的返回值。
* @author shkstart
* @date 2019年2月12日上午12:04:45
* @return
*/
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;
}
}
项目源代码和开发文档提供如下:
链接:https://pan.baidu.com/s/14mHrhTOLrVP7n0ZdZ_kKRQ
提取码:2fxi
复制这段内容后打开百度网盘手机App,操作更方便哦--来自百度网盘超级会员V5的分享