Java学习笔记 | 尚硅谷项目三详解

该笔记基于B站视频:尚硅谷Java入门视频教程

在这里插入图片描述

1,目标

  • 模拟实现一个基于文本界面的《开发团队调度软件》
  • 熟悉Java面向对象的高级特性,进一步掌握编程技巧和调试技巧
  • 主要涉及以下知识点:
    • 类的继承性和多态性
    • 对象的值传递、接口
    • static和final修饰符
    • 特殊类的使用:包装类、抽象类、内部类
    • 异常处理

2,需求说明

2.1,功能实现

  • 该软件实现以下功能:
    • 软件启动时,根据给定的数据创建公司部分成员列表(数组)
    • 根据菜单提示,基于现有的公司成员,组建一个开发团队以开发一个新的项目
    • 组建过程包括将成员插入到团队中,或从团队中删除某成员,还可以列出团队中现有成员的列表
    • 开发团队成员包括架构师、设计师和程序员

2.1,菜单显示

本软件采用单级菜单方式工作。当软件运行时,主界面显示公司成员的列表,如下:
菜单显示

2.2,添加功能

当选择“添加团队成员”菜单时,将执行从列表中添加指定(通过ID)成员到开发团队的功能:
添加功能
添加成功后,按回车键将重新显示主界面。
添加成功
如果添加操作因某种原因失败,将显示类似以下信息(失败原因视具体原因而不同):
添加失败
添加失败的原因可能有:

失败信息包含以下几种:

  • 成员已满,无法添加
  • 该成员不是开发人员,无法添加
  • 该员工已在本开发团队中
  • 该员工已是某团队成员
  • 该员正在休假,无法添加
  • 团队中至多只能有一名架构师
  • 团队中至多只能有两名设计师
  • 团队中至多只能有三名程序员

2.3,删除功能

当选择“删除团队成员”菜单时,将执行从开发团队中删除指定(通过TeamID)成员的功能:
删除成功删除成功后,按回车键将重新显示主界面。

2.3,查看团队成员

当选择“团队列表”菜单时,将列出开发团队中的现有成员,例如:
查看团队成员

3,软件设计结构

该软件由以下三个模块组成:
软件设计结构
MVC:M:domain;V:view ;C:service

  • view模块为主控模块,负责菜单的显示和处理用户操作
  • service模块为实体对象(Employee及其子类如程序员等)的管理模块, NameListService和TeamService类分别用各自的数组来管理公司员工和开发团队成员对象
  • domain模块为Employee及其子类等JavaBean类所在的包
    代码结构如下:
    在这里插入图片描述

domain模块中包含了所有实体类:
软件设计结构

4,具体实现

4.1,第一步:创建项目基本组件

  1. 完成以下工作:
  • 创建TeamSchedule项目
  • 按照设计要求,创建所有包
  • 将项目提供的几个类复制到相应的包中 (view包中:TSUtility.java; service包中:Data.java)
  1. 按照设计要求,在domain包中,创建Equipment接
    口及其各实现子类代码
  2. 按照设计要求,在domain包中,创建Employee类
    及其各子类代码
  3. 检验代码的正确性
    TSUtility:
package Project3.view;

import java.util.*;
/**
 * @Description 项目中提供了TSUtility.java类,可用来方便地实现键盘访问。
 */
public class TSUtility {
    private static Scanner scanner = new Scanner(System.in);
    /**
     * @Description 该方法读取键盘,如果用户键入’1’-’4’中的任意字符,则方法返回。返回值为用户键入字符。
     */
	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 该方法提示并等待,直到用户按回车键后返回。
	 */
    public static void readReturn() {
        System.out.print("按回车键继续...");
        readKeyBoard(100, true);
    }
    /**
     * @Description 该方法从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
     */
    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’,并将其作为方法的返回值。
     */
    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;
    }
}


Data:

package Project3.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"}
    };
}

Status的定义:

package Project3.service;
//表示员工的状态
public class Status {
	private final String NAME;
	private Status(String NAME) {
		this.NAME=NAME;
	}
	public static final Status FREE=new Status("FREE");
	public static final Status BUSY=new Status("BUSY");
	public static final Status VOCATION=new Status("VOCATION");
	public String getNAME() {
		return NAME;
	}

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

4.1.1,键盘访问的实现

  • 项目view包中提供了TSUtility.java类,可用来方便地实现键盘访问。
  • 该类提供了以下静态方法:
    • public static char readMenuSelection()
      用途:该方法读取键盘,如果用户键入’1’-’4’中的任意字符,则方法返回。返回值为用户键入字符。
    • public static void readReturn()
      用途:该方法提示并等待,直到用户按回车键后返回。
    • public static int readInt()
      用途:该方法从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
    • public static char readConfirmSelection() :
      用途:从键盘读取‘Y’或’N’,并将其作为方法的返回值。
package Project3.view;

import java.util.*;
/**
 * @Description 项目中提供了TSUtility.java类,可用来方便地实现键盘访问。
 */
public class TSUtility {
    private static Scanner scanner = new Scanner(System.in);
    /**
     * @Description 该方法读取键盘,如果用户键入’1’-’4’中的任意字符,则方法返回。返回值为用户键入字符。
     */
	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 该方法提示并等待,直到用户按回车键后返回。
	 */
    public static void readReturn() {
        System.out.print("按回车键继续...");
        readKeyBoard(100, true);
    }
    /**
     * @Description 该方法从键盘读取一个长度不超过2位的整数,并将其作为方法的返回值。
     */
    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’,并将其作为方法的返回值。
     */
    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;
    }
}


4.1.2,Equipment接口及其实现子类的设计

Equipment接口

  • 说明:
    • model 表示机器的型号
    • display 表示显示器名称
    • type 表示机器的类型
  • 根据需要提供各属性的get/set方法以及重载构造器
  • 实现类实现接口的方法,返回各自属性的信息
    equipment:
package Project3.domain;

public interface Equipment {
	String getDescription();
}

NoteBook:

package Project3.domain;

public class NoteBook implements Equipment{
	private String model;//機器型號
	private double 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;
	}
	public NoteBook(String model, double price) {
		super();
		this.model = model;
		this.price = price;
	}
	public NoteBook() {
		super();
	}
	@Override
	public String getDescription() {
		// TODO 自动生成的方法存根
		return model+"("+price+")";
	}
	

}

PC:

package Project3.domain;

public class PC implements Equipment{
	private String model;//机器型号
	private String display;//显示器名称
	
	public PC(String model, String display) {
		super();
		this.model = model;
		this.display = display;
	}

	public PC() {
		super();
	}

	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+")";
	}

}

Printer:

package Project3.domain;

public class Printer implements Equipment{
	private String name;//机器型号
	private String 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;
	}
	public Printer(String name, String type) {
		super();
		this.name = name;
		this.type = type;
	}
	public Printer() {
		super();
	}
	@Override
	public String getDescription() {
		// TODO 自动生成的方法存根
		return name+"("+type+")";
	}
	
}

4.1.3,Employee类及其子类的设计

Equipment类的实现

  • 说明:
    • memberId 用来记录成员加入开发团队后在团队中的ID
    • Status是项目service包下自定义的类,声明三个对象属性,分别表示成员的状态。
      • FREE-空闲
      • BUSY-已加入开发团队
      • VOCATION-正在休假
    • equipment 表示该成员领用的设备
  • 可根据需要为类提供各属性的get/set方法以及重载构造器
    Employee:
package Project3.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 getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	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 double getSalary() {
		return salary;
	}

	public void setSalary(double salary) {
		this.salary = salary;
	}

	protected String getDetails() {
		return id + "\t" + name + "\t" + age+ "\t" +salary;
	}

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

Programmer:

package Project3.domain;

import Project3.service.Status;

public class Programmer extends Employee {
	private int memberId;
	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 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;
	}

	public int getMemberId() {
		return memberId;
	}

	public void setMemberId(int memberId) {
		this.memberId = memberId;
	}

	protected String getMemberDetails() {
		return getMemberId() + "/" +"\t"+getDetails();
	}

	public String getDetailsForTeam() {
		return getMemberDetails() + "\t程序员";
	}

	@Override
	public String toString() {
		return getDetails() + "\t程序员\t" + status + "\t\t\t\t\t\t" + equipment.getDescription() ;
	}
}

在这里插入图片描述

  • 说明:
    • bonus 表示奖金
    • stock 表示公司奖励的股票数量
  • 可根据需要为类提供各属性的get/set方法以及重载构造器
    Designer:
package Project3.domain;

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;
	}

	public double getBonus() {
		return bonus;
	}

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

	public String getDetailsForTeam() {
		return getMemberDetails() + "\t设计师\t" + getBonus();
	}

	@Override
	public String toString() {
		return getDetails() + "\t设计师\t" + getStatus() + "\t" +
				getBonus() +"\t\t\t\t" + getEquipment().getDescription();
	}
}

Architect:

package Project3.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 getDetails() + "\t架构师\t" + getStatus() + "\t" +
				getBonus() + "\t\t" + getStock() + "\t" + getEquipment().getDescription();
	}
}

4.1.4,Status类

Status枚举类位于com.atguigu.team.service包中,封装员工的状态。其代码如下:

package service;
public class Status {
    private final String NAME;
    private Status(String name) {
        this.NAME = name;
    }
    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;
    }
} 

4.2,第二步:实现service包中的类

  1. 按照设计要求编写NameListService类
  2. 在NameListService类中临时添加一个main方法中,作为单元测试方法。
  3. 在方法中创建NameListService对象,然后分别用模拟数据调用该对象的各个方法,以测试是否正确。
    注:测试应细化到包含了所有非正常的情况,以确保方法完全正确。
  4. 重复1-3步,完成TeamService类的开发

4.2.1,NameListService类的设计

在这里插入图片描述

  • 功能:负责将Data中的数据封装到Employee[]数组中,同时提供相关操作Employee[]的方法。
  • 说明:
    • employees用来保存公司所有员工对象
    • NameListService()构造器:
    • 根据项目提供的Data类构建相应大小 的employees数组
    • 再根据Data类中的数据构建不同的对象,包括Employee、Programmer、Designer和Architect对象,以及相关联的Equipment子类的对象
    • 将对象存于数组中
    • Data类位于com.atguigu.team.service包中

在这里插入图片描述

  • 说明:
    • getAllEmployees ()方法:获取当前所有员工。
      • 返回:包含所有员工对象的数组
    • getEmployee(id : int)方法:获取指定ID的员工对象。
      • 参数:指定员工的ID
      • 返回:指定员工对象
      • 异常:找不到指定的员工
  • 在service子包下提供自定义异常类:TeamException
  • 另外,可根据需要自行添加其他方法或重载构造器
    NameListService:
package Project3.service;

import Project3.domain.Architect;
import Project3.domain.Designer;
import Project3.domain.Employee;
import Project3.domain.Equipment;
import Project3.domain.NoteBook;
import Project3.domain.PC;
import Project3.domain.Printer;
import Project3.domain.Programmer;

import static Project3.service.Data.*;
/**
 * @Description 负责将Data中的数据封装到Employee[]数组中,同时提供相关操作Employee[]的方法。
 *
 */
public class NameListService {
	private Employee[] employees;

	public NameListService() {
		employees = new Employee[EMPLOYEES.length];

		for (int i = 0; i < employees.length; i++) {
			// 获取通用的属性
			int type = 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 eq;
			double bonus;
			int stock;

			switch (type) {
				case EMPLOYEE:
					employees[i] = new Employee(id, name, age, salary);
					break;
				case PROGRAMMER:
					eq = createEquipment(i);
					employees[i] = new Programmer(id, name, age, salary, eq);
					break;
				case DESIGNER:
					eq = createEquipment(i);
					bonus = Integer.parseInt(EMPLOYEES[i][5]);
					employees[i] = new Designer(id, name, age, salary, eq, bonus);
					break;
				case ARCHITECT:
					eq = createEquipment(i);
					bonus = Integer.parseInt(EMPLOYEES[i][5]);
					stock = Integer.parseInt(EMPLOYEES[i][6]);
					employees[i] = new Architect(id, name, age, salary, eq, bonus,
							stock);
					break;
			}
		}
	}

	private Equipment createEquipment(int index) {
		int type = Integer.parseInt(EQUIPMENTS[index][0]);
		switch (type) {
			case PC:
				return new PC(EQUIPMENTS[index][1], EQUIPMENTS[index][2]);
			case NOTEBOOK:
				int price = Integer.parseInt(EQUIPMENTS[index][2]);
				return new NoteBook(EQUIPMENTS[index][1], price);
			case PRINTER:
				return new Printer(EQUIPMENTS[index][1], EQUIPMENTS[index][2]);
		}
		return null;
	}

	public Employee[] getAllEmployees() {
		return employees;
	}

	public Employee getEmployee(int id) throws TeamException {
		for (Employee e : employees) {
			if (e.getId() == id)
				return e;
		}
		throw new TeamException("该员工不存在");
	}
}

4.2.2,TeamService类的设计

在这里插入图片描述

  • 功能:关于开发团队成员的管理:添加、删除等。

  • 说明:

    • counter为静态变量,用来为开发团队新增成员自动生成团队中的唯一ID,即memberId。(提示:应使用增1的方式)
    • MAX_MEMBER:表示开发团队最大成员数
    • team数组:用来保存当前团队中的各成员对象
    • total:记录团队成员的实际人数
      在这里插入图片描述
  • 说明:

    • getTeam()方法:返回当前团队的所有对象
      • 返回:包含所有成员对象的数组,数组大小与成员人数一致
    • addMember(e: Employee)方法:向团队中添加成员
      • 参数:待添加成员的对象
      • 异常:添加失败, TeamException中包含了失败原因
    • removeMember(memberId: int)方法:从团队中删除成员
      • 参数:待删除成员的memberId
      • 异常:找不到指定memberId的员工,删除失败
  • 另外,可根据需要自行添加其他方法或重载构造器
    TeamException:

package Project3.service;
/**
 * @Description 自定义异常类
 */
public class TeamException extends Exception{
	 static final long serialVersionUID = -3387516912124229948L;
	 public TeamException() {
		 
	 }
	 public TeamException(String msg) {
		 super(msg);
	 }
}

TeamService:

package Project3.service;

import Project3.domain.Architect;
import Project3.domain.Designer;
import Project3.domain.Employee;
import Project3.domain.Programmer;

public class TeamService {
    private static int counter = 1;//给memberId赋值
    private final int MAX_MEMBER = 5;//限制开发团队的成员
    private Programmer[] team = new Programmer[MAX_MEMBER];//保存开发团队成员
    private int total = 0;//记录开发团队实际的人数

    public TeamService() {

    }

    //获取开发团队中所有的成员
    public Programmer[] getTeam() {
        Programmer[] team = new Programmer[total];
        for (int i = 0; i < team.length; i++) {
            team[i] = this.team[i];
        }
        return team;
    }

    //将指定的员工添加到开发团队中
    public void addMember(Employee e) throws TeamException {
        //成员已满,无法添加
        if (total >= MAX_MEMBER) {
            throw new TeamException("成员已满,无法添加");
        }
        //该成员不是开发人员,无法添加
        if (!(e instanceof Programmer)) {
            throw new TeamException("该成员不是开发人员,无法添加");
        }
        //该员工已在本开发团队中
        isExist(e);
        //该员工已是某团队成员
        //该员正在休假,无法添加
        Programmer p = (Programmer) e;//一定不会出现ClassCastException
        if ("BUSY".equals(p.getStatus().getNAME())) {
            throw new TeamException("该员工已是某团队成员");
        } else if ("VOCATION".equals(p.getStatus().getNAME())) {
            throw new TeamException("该员正在休假,无法添加");
        }
        //团队中至多只能有一名架构师

        //团队中至多只能有两名设计师

        //团队中至多只能有三名程序员

        //获取程序中已有的成员中架构师、设计师、程序员的认识
        int numOfArch = 0, numOfDes = 0, numOfPro = 0;
        for (int i = 0; i < total; i++) {
            if (team[i] instanceof Architect) {
                numOfArch++;
            } else if (team[i] instanceof Designer) {
                numOfDes++;
            } else if (team[i] instanceof Programmer) {
                numOfPro++;
            }
        }
        if (p instanceof Architect) {
            if (numOfArch >= 1) {
                throw new TeamException("团队中至多只能有一名架构师");
            } else if (numOfDes >= 2) {
                throw new TeamException("团队中至多只能有两名设计师");
            } else if (numOfPro >= 3) {
                throw new TeamException("团队中至多只能有三名程序员");
            }
        }
        //将p添加到现有的team中
        team[total++] = p;
        p.setStatus(Status.BUSY);
        p.setMemberId(counter++);
    }

    //该员工已在本开发团队中
    private Boolean isExist(Employee e) {
        for (int i = 0; i < total; i++) {
            if (team[i].getId() == e.getId()) {
                return true;
            }
        }
        return false;
    }

    //从团队当中删除成员
    public void removeMember(int memberId) throws TeamException {
        int i = 0;
        for (i = 0; i < total; i++) {
            if (team[i].getMemberId() == memberId) {
                team[i].setStatus(Status.FREE);
                break;
            }
        }
        //未找到指定id的成员
        if (i == total) {
            throw new TeamException("找不到指定memberId的员工,删除失败");
        }
        //后边的元素覆盖前一个元素,实现删除操作
        for (int j = i + 1; j < total; j++) {
            team[j - 1] = team[j];
        }
        team[--total] = null;
    }
}

4.3,第三步:实现view包中类

  1. 按照设计要求编写TeamView类,逐一实现各个方法,并编译
  2. 执行main方法中,测试软件全部功能

4.3.1,TeamView类的设计

在这里插入图片描述

  • 说明:
    • listSvc和teamSvc属性:供类中的方法使用
    • enterMainMenu ()方法:主界面显示及控制方法。
    • 以下方法仅供enterMainMenu()方法调用:
      • listAllEmployees ()方法:以表格形式列出公司所有成员
      • getTeam()方法:显示团队成员列表操作
      • addMember ()方法:实现添加成员操作
      • deleteMember ()方法:实现删除成员操作
        TeamView:
package Project3.view;

import Project3.domain.Employee;
import Project3.domain.Programmer;
import Project3.service.NameListService;
import Project3.service.TeamException;
import Project3.service.TeamService;

public class TeamView {
    private NameListService listSvc = new NameListService();
    private TeamService teamSvc = new TeamService();

    public void enterMainMenu() {
        boolean loopFlag = true;
        char menu = 0;
        while (loopFlag) {
            if (menu != '1') {
                listAllEmployees();
            }
            System.out.println("1-团队列表  2-添加团队成员  3-删除团队成员 4-退出   请选择(1-4):");
            menu = TSUtility.readMenuSelection();
            switch (menu) {
                case '1':
                    getTeam();
                    break;
                case '2':
                    addMember();
                    break;
                case '3':
                    deleteMember();
                    break;
                case '4':
                    System.out.println("确认是否退出(Y/N):");
                    char isExit = TSUtility.readConfirmSelection();
                    if (isExit == 'Y') {
                        loopFlag = false;
                    }
                    break;
            }
        }
    }

    //显示所有的员工信息
    private void listAllEmployees() {
//        System.out.println("显示公司所有成员的信息");
        System.out.println("\n-------------------------------开发团队调度软件--------------------------------\n");
        Employee[] employees = listSvc.getAllEmployees();
        if (employees == null || employees.length == 0) {
            System.out.println("公司中没有任何员工信息!");
        } else {
            System.out.println("ID\t姓名\t\t年龄\t工资\t\t职位\t\t状态\t\t奖金\t\t\t股票\t\t领用设备");
            for (int i = 0; i < employees.length; i++) {
                System.out.println(employees[i]);
            }
        }
        System.out.println("-------------------------------------------------------------------------------");
    }

    //
    private void getTeam() {
        System.out.println("\n--------------------团队成员列表---------------------\n");
        Programmer []team= teamSvc.getTeam();
        if (team==null){
            System.out.println("开发团队目前没有成员");
        }else{
            System.out.println("TID/ID\t姓名\t\t年龄\t工资\t\t职位\t\t奖金\t\t\t股票\n");
            for (int i = 0; i < team.length; i++) {
                System.out.println(team[i].getDetailsForTeam());
            }
        }
        System.out.println("-----------------------------------------------------");
    }

    private void addMember() {
//        System.out.println("添加团队成员");
        System.out.println("---------------------添加成员---------------------");
        System.out.print("请输入要添加的员工ID:");
        int id = TSUtility.readInt();

        try {
            Employee e = listSvc.getEmployee(id);
            teamSvc.addMember(e);
            System.out.println("添加成功");
        } catch (TeamException e) {
            System.out.println("添加失败,原因:" + e.getMessage());
        }
        // 按回车键继续...
        TSUtility.readReturn();
    }


    private void deleteMember() {
//        System.out.println("删除团队成员");
        System.out.println("---------------------删除成员---------------------");
        System.out.print("请输入要删除员工的TID:");
        int id = TSUtility.readInt();
        System.out.print("确认是否删除(Y/N):");
        char yn = TSUtility.readConfirmSelection();
        if (yn == 'N')
            return;

        try {
            teamSvc.removeMember(id);
            System.out.println("删除成功");
        } catch (TeamException e) {
            System.out.println("删除失败,原因:" + e.getMessage());
        }
        // 按回车键继续...
        TSUtility.readReturn();
    }

    public static void main(String[] args) {
        TeamView view = new TeamView();
        view.enterMainMenu();
    }
}

5,总结

好难,但是有用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Yooki_Wang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值