package domain; public interface Equipment { //这个方法的作用要看实例项目的运行.根据运行我们知道是对输出结果进行 //相应的修改.功能类似于toString().为什么不直接用toString()呢? //因为接口不能继承类.所有没有Object中的toString(). //关于接口中方法的语法说明:接口中的方法默认都是public abstract.所以 //可以省略不写public abstract. //另外接口也是可以定义实体方法的.使用default即可. public abstract String getDescription(); }
package domain; public class NoteBook implements Equipment { private String model; private double price; public NoteBook(String model, double price) { this.model = model; this.price = price; } public NoteBook() { } 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 //因为实现了Equipment接口.所以需要重写getDescription(),这个方法 public String getDescription() { return model+"("+price+")"; } }
package 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 getDescription() { return model + "(" +display+")"; } }
package domain; 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; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getType() { return type; } public void setType(String type) { this.type = type; } @Override public String getDescription() { return name+"(" +type +")"; } }
package 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 details() { return id + "t" + name + "t" + age + "t" + salary; } @Override public String toString() { return details(); } }
package domain; import service.Status; public class Programmer extends Employee { //团队Id,就是每个程序员以及他子类的对象都可以添加到 //项目要求的团队中.然后给他们的这个属性进行赋值修改. private int memberId; public int getMemberId() { return memberId; } public void setMemberId(int memberId) { this.memberId = memberId; } //状态:空闲/繁忙,这个属性比较难.难在它的创建方式. //首先她是一个引用数据类型.然后就是他的赋值方式 //很显然使用的类.属性的方式,该属性一定是静态的. //那么这个属性引用了什么呢.来看Status类. private Status status = Status.FREE; public Status getStatus() { return status; } public void setStatus(Status status) { this.status = status; } private Equipment equipment; public Programmer() { } public Programmer(int id, String name, int age, double salary, Equipment equipment) { //super关键字指的是当前对象父类的特征.如果需要父类的某些成员(不能是私有的),可以通过 //super调用. super(id, name, age, salary); this.equipment = equipment; } public Equipment getEquipment() { return equipment; } public void setEquipment(Equipment equipment) { this.equipment = equipment; } @Override public String toString() { //现在还体会不到details方法的作用,在下一级就能体会到了.因为下面要 //根据对象的不同来输出 "程序员"就这一点变动.其实这里这里可以定义一个变量存放这个字符串的 //然后就只需要重写toString()不需要拼的这么辛苦. //equipment.getDescription();我们之前在Equipment接口讲过这个方法的作用就是输出不同类的 //字符创拼接结果,使用的是多态. return details() +"t程序员"+"t"+status.getNAME()+"ttttt"+equipment.getDescription(); } }
package domain; public class Designer extends Programmer{ //奖金 private double bonus; public Designer(int id, String name, int age, double salary, Equipment equipment, double bonus) { super(id, name, age, salary, equipment); this.bonus = bonus; } public Designer() { } public double getBonus() { return bonus; } public void setBonus(double bonus) { this.bonus = bonus; } @Override public String toString() { //这里就体会到了.details的作用了.其实details应该放在Programer.会更好. return details() +"t设计师"+"t"+getStatus().getNAME()+"ttt"+bonus+"t"+getEquipment().getDescription(); } }
package domain; 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; } public int getStock() { return stock; } public void setStock(int stock) { this.stock = stock; } @Override public String toString() { return details()+"t"+"架构师"+"t"+ getStatus().getNAME()+"t"+getBonus()+"t"+stock+"t"+getEquipment().getDescription(); } }package service;
package 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"} }; //如下的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"} }; }
package service; public class Status { private final String NAME; //私有化构造器,外部不能创建对象. private Status(String name) { this.NAME = name; } //其实就是单例模式.不同的是单例模式静态的是方法,它这里静态的是属性. //final 只针对的变量只在当前作用域生效. public static final Status FREE = new Status("FREE"); public static final Status VOCATION = new Status("VOCATION"); public static final Status BUSY = new Status("BUSY"); public String getNAME() { return NAME; } @Override public String toString() { return NAME; } }
package service; import domain.PC; import domain.*; import static service.Data.*; public class NameListService { private Employee[] employees; //我们在空参构造中将数组赋值,并且不在提供其他构造,方便每次new NameListService()只有一个数组 //这个数组的值同时也被确定好了. public NameListService() { //首先确定好数组的长度. employees = new Employee[EMPLOYEES.length]; //这些变量定义在后面的循环外面是为了节约内存,不用每次循环都要定义一次. //为什么明明是局部变量但没赋值又不会报错呢,因为下面每次使用前都赋值了,不存在没赋值就使用的情况. int type; int id; String name; int age; double salary; double bonus; //遍历的这一步我当出看实例代码才想到,因为要将Data中的数据取出来,就必须遍历一个一个取出来赋值. //我们定义的数组是Employee类型,只能存入Employee对象,所以现在目标只有一个就是创建Employee对象 //使用Data中的数据给Employee对象赋值. for (int i = 0; i < EMPLOYEES.length; i++) { //得到二维数组EMPLOYEES每个一维中的第一个作为员工的类型. //我们刚才观察Data数据可知.每个数组二维的第一数据确定类型.那么我们就将他取出来作为类型 //同时我们还知道Data中有常量表示这些类型,那好办了. //因为都是字符串,而我们的常量是int型,所以需要使用包装类相关知识中的字符串转基本数据类型 //包装类.parsexxx(). type = Integer.parseInt(EMPLOYEES[i][0]); //下面这四个数据都是Employee类以及其子类有的属性.所以也取出来. //这里不方便使用两层循环,因为转换方式不一样.干脆直接用一层,内层就根据实际来. id = Integer.parseInt(EMPLOYEES[i][1]); name = EMPLOYEES[i][2]; age = Integer.parseInt(EMPLOYEES[i][3]); salary = Double.parseDouble(EMPLOYEES[i][4]); //然后根据我们的类型创建相应的对象.一一赋值. switch (type) { case EMPLOYEE: employees[i] = new Employee(id, name, age, salary); break; case PROGRAMMER: //到这里的下面就需要Equipment对象了.因为有这个属性.这里不方便直接取出Data中的 //Equipment对象进行赋值.所以我们创建一个方法返回Equipment对象即可. employees[i] = new Programmer(id, name, age, salary, creatEq(i)); break; case DESIGNER: //根据类型的需要,也就是子类多一些属性.自定义变量.为什么不用担心空指针,比如 //EMPLOYEES[i][5]没有5之类的.因为根据类型来,Data中的数据已经定义好了.不会出现这种情况. bonus = Double.parseDouble(EMPLOYEES[i][5]); employees[i] = new Designer(id, name, age, salary, creatEq(i), bonus); break; case ARCHITECT: bonus = Double.parseDouble(EMPLOYEES[i][5]); int stock = Integer.parseInt(EMPLOYEES[i][6]); employees[i] = new Architect(id, name, age, salary, creatEq(i), bonus, stock); break; } } } private Equipment creatEq(int i) { int key = Integer.parseInt(EQUIPMENTS[i][0]); String model; String display; Equipment equipment; double price; String name; String type; switch (key) { case PC: model = EQUIPMENTS[i][1]; display = EQUIPMENTS[i][2]; equipment = new PC(model, display); break; case NOTEBOOK: model = EQUIPMENTS[i][1]; price = Double.parseDouble(EQUIPMENTS[i][2]); equipment = new NoteBook(model, price); break; case PRINTER: name = EQUIPMENTS[i][1]; type = EQUIPMENTS[i][2]; equipment = new Printer(name, type); break; default: equipment = null; } return equipment; } public Employee[] getAllEmployees() { return employees; } public Employee getEmployee(int id) throws TeamException { for (int i = 0; i < EMPLOYEES.length; i++) { if (id==employees[i].getId()){ return employees[i]; } } throw new TeamException("该员工不存在"); } }
package service; public class TeamException extends Exception { //系列化版本号 static final long serialVersionUID = -33875169124229948L; public TeamException() { } public TeamException(String message) { super(message); } }
package service; import domain.Architect; import domain.Designer; import domain.Employee; import domain.Programmer; public class TeamService { // counter为静态变量,用来为开发团队新增成员自动生成团队中的唯一ID, // 即memberId。(提示:应使用增1的方式) private static int counter = 1; //表示开发团队最大成员数 private final int MAX_MEMBER = 5; //用来保存当前团队中的各成员对象,使用创建对象来当属性,说明外部 //如果创建当前类TeamService的对象,该对象的属性中有个Programmer[]. //无论怎么 *** 作都是同一个数组.想不懂可以画内存图. private Programmer[] team = new Programmer[MAX_MEMBER]; //记录团队成员的实际人数 private int total = 0; public int getTotal() { return total; } public Programmer[] getTeam() { return team; } //往团队中增加成员 public void addMember(Employee e) throws TeamException { if (total >= MAX_MEMBER) { throw new TeamException("成员已满,无法添加"); } //走到这,说明人员没满. if (!(e instanceof Programmer)) { throw new TeamException("该成员不是开发人员,无法添加"); } //走到这说明是开发人员.那么下一步可以强转成开发人员,而且必定成功. Programmer p = (Programmer)e; if (Status.BUSY.equals(p.getStatus())){ throw new TeamException("该员工已在本开发团队中"); } //走到这说明他不在开发团队当中. if(Status.VOCATION.equals(p.getStatus())){ throw new TeamException("该员正在休假,无法添加"); } //走到这该开发人员一定是空闲的.那么就看团队目前情况了. //我们可以统计一下里面有多少架构师,设计师以及开发人员 int countA=0,countD=0,countP=0; for (int i = 0; i < total; i++) { if(team[i] instanceof Architect){ countA++; } if(team[i] instanceof Designer){ countD++; } } //因为如果是架构师,设计师也会被判定为true. countD=countD-countA; countP=total-countA-countD; //如果传进来的是架构师. if(p instanceof Architect) { if (countA > 0) { throw new TeamException("团队中至多只能有一名架构师"); } }else if(p instanceof Designer){ if(countD>1){ throw new TeamException("团队中至多只能有两名设计师"); } }else{ if(countP>2){ throw new TeamException("团队中至多只能有三名程序员"); } } //走到这了,那说明都满足条件.可以添加. //先将memberId设置为1,然后将counter++,变成2.方便下一个添加进来的. p.setMemberId(counter++); //将索引为0也就是第一个位置给p,然后将索引往后推1. team[total++] = p; //加进去后将p的状态改为BUSY.因为是同一对象.在内存中都是指向同一个属性. //所以先后顺序没影响. p.setStatus(Status.BUSY); } //删除团队成员 public void removeMember(int memberId) throws TeamException { for (int i = 0; i < total; i++) { if(memberId == team[i].getMemberId()){ //如果找到了该成员,先改为空闲,然后后面的成员往前覆盖. team[i].setStatus(Status.FREE); //total表示的是实际人数,total-1才是索引. for (int j = i; j < total -1; j++) { team[j] = team[j+1]; } //最后一个置空. team[--total] = null; } } throw new TeamException("删除失败,原因:找不到该成员,无法删除"); } }package view;
package 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 read/confirm/iSelection() { 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; } } ```java package view; import domain.Employee; import domain.Programmer; import service.NameListService; import service.TeamException; import service.TeamService; public class TeamView { //这里将对象作为属性,那么在当前类就会只有一个,怎么 *** 作都是 *** 作同一个. //这个是之前存放Data数据的Employee[]; NameListService listSvc = new NameListService(); //这个是Programmer[] team. TeamService teamSvc = new TeamService(); //同理,声明在外面的变量,是为了不在循环里重复声明. Employee employee; char key = '0'; int id; char yn; //主界面显示及控制方法。 public void enterMainMenu() { //声明它作为一个标记,方便结束循环. boolean isFlag = true; while (isFlag) { //这个挺巧妙的,如果你们运行会发现,展示开发团队后并没有再次输出列表. if (key != '1') { System.out.println("-------------------------------开发团队调度软件--------------------------n"); System.out.println("IDt姓 名t年龄t工资tt职位tt状态tt奖金tt股票tt领用设备"); listAllEmployees(); } System.out.println("-------------------------------------------------------------------------"); System.out.print("1-团队列表 2-添加团队成员 3-删除团队成员 4-退出 请选择(1-4): "); key = TSUtility.readMenuSelection(); System.out.println(); //将接收的结果直接作为选择的值. switch (key) { case '1': getTeam(); break; case '2': addMember(); break; case '3': deleteMember(); break; case '4': System.out.print("确认是否退出(Y/N):"); yn = TSUtility.read/confirm/iSelection(); if (yn == 'Y') { isFlag = false; } break; } } } //以表格形式列出公司所有成员 public void listAllEmployees() { Employee[] aE = listSvc.getAllEmployees(); for (Employee list : aE) { System.out.println(list); } } //显示团队成员列表 *** 作 public void getTeam() { System.out.println("--------------------团队成员列表---------------------n"); Programmer[] team = teamSvc.getTeam(); if (teamSvc.getTotal() != 0) { System.out.println("TID/IDt姓名t年龄t工资t职位t奖金t股票"); //这里不能用for-each因为只能遍历total,如果遍历全部会出现空指针. for (int i = 0; i < teamSvc.getTotal(); i++) { //return id+ "t" + name + "t"+age+"t"+salary; //details()+"t"+"架构师"+"t"+ getStatus().getNAME()+"t"+getBonus()+"t"+stock System.out.println(" "+ team[i].getMemberId()+"/"+team[i]); } } else { System.out.println("开发团队目前没有成员!"); } } //实现添加成员操作 public void addMember() { System.out.println("---------------------添加成员---------------------"); System.out.print("请输入要添加的员工ID:"); id = TSUtility.readInt(); //之前这里要抛异常对吧,现在统一处理.如果要抛异常,那么通过自定义异常类的对象.getMessage()输出 //自定义的语句. try { employee = listSvc.getEmployee(id); teamSvc.addMember(employee); System.out.println("添加成功"); } catch (TeamException e) { System.out.println("添加失败:"); System.out.println(e.getMessage()); } TSUtility.readReturn(); } //实现删除成员操作 public void deleteMember() { System.out.println("---------------------删除成员---------------------"); System.out.print("请输入要删除员工的TID:"); id = TSUtility.readInt(); System.out.print("确认是否删除(Y/N):"); yn = TSUtility.read/confirm/iSelection(); if(yn=='Y'){ try { teamSvc.removeMember(id); } catch (TeamException e) { System.out.println(e.getMessage()); } } } }
```java package view; public class TeamViewTest { public static void main(String[] args) { TeamView teamView = new TeamView(); teamView.enterMainMenu(); } }
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)