day04 【综合练习】
今日内容
- 案例演示
- 设计类
- 制作类
- 实现功能(对学生信息的增删查改的功能)
第一章 案例演示
1.1 程序启动
运行com.itheima.main.MainApp类,启动程序:
1.2 测试学员信息管理模块
1.3 测试【4.查询学员】
1.4 测试【1.添加学员】
1.5 测试【2.修改学员】
-
输入不存在的编号:
-
输入存在的编号:
1.6 测试【3.删除学员】
-
输入不存在的编号:
-
输入存在的编号,但取消操作:
-
输入存在的编号,执行删除:
业务逻辑分析:
第二章 类设计
2.1 父类Person(抽象)
成员变量: 编号,姓名,性别,出生日期,年龄
构造方法: 无参构造,满参构造
成员方法:
public String show(){
return "我是一名:"+getType()+",我的工作是:"+getWork();
}
public abstract String getType();
public abstract String getWord();
2.2 子类Student
构造方法: 无参构造,满参构造
成员方法:
重写getType()方法,返回学生
重写getWork()方法,返回学习Java
2.3 子类Teacher
构造方法: 无参构造,满参构造
成员方法:
重写getType()方法,返回教师
重写getWork()方法,返回教Java
2.4 工具类Utils类
1.定义一个根据出生日期计算年龄的静态方法
2.定义一个方法,用来按照指定格式打印输出集合中的元素内容(学生对象,教师对象)
3.定义一个方法,用来按照指定格式打印Person对象
2.5 启动类
一级菜单,二级菜单,添加,查询,修改,删除
第三章 类制作
3.1 父类Person(抽象)
public abstract class Person {
// 编号
private int id;
// 姓名
private String name;
// 性别
private String sex;
// 出生日期
private String birthday;
// 年龄
private int age;
// 空参,满参构造
public Person() {
}
public Person(int id, String name, String sex, String birthday, int age) {
this.id = id;
this.name = name;
this.sex = sex;
this.birthday = birthday;
this.age = age;
}
// set\get方法
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 String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 成员方法
public String show(){
return "我是一名:"+getType()+",我的工作是:"+getWork();
}
public abstract String getType();
public abstract String getWork();
}
3.2 子类Student
public class Student extends Person {
public Student() {
}
public Student(int id, String name, String sex, String birthday, int age) {
super(id, name, sex, birthday, age);
}
@Override
public String getType() {
return "学生";
}
@Override
public String getWork() {
return "学Java";
}
}
3.3 子类Teacher
public class Teacher extends Person {
public Teacher() {
}
public Teacher(int id, String name, String sex, String birthday, int age) {
super(id, name, sex, birthday, age);
}
@Override
public String getType() {
return "教师";
}
@Override
public String getWork() {
return "教Java";
}
}
3.4 工具类Utils类
public class Utils {
public static int sid;// 重启程序,sid会重新定义,也就是又从0开始
public static int tid;// 重启程序,tid会重新定义,也就是又从0开始
static {
// 以后,sid,tid的初始值从数据库中,或者文件中获取最后一个id的值作为初始值
sid = 0;
tid = 0;
}
// 1.定义一个根据出生日期计算年龄的静态方法
public static int birthdayToAge(String birthday) throws ParseException {
// 1.把字符串类型的出生日期转换为Date类型的出生日期
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date birthdayDate = sdf.parse(birthday);
// 2.获取当前时间对应的日历对象,通过该日历对象获取当前的年,月,日
Calendar cal = Calendar.getInstance();
int nowYear = cal.get(Calendar.YEAR);
int nowMonth = cal.get(Calendar.MONTH);
int nowDay = cal.get(Calendar.DAY_OF_MONTH);
// 3.获取出生日期对应的日历对象,通过该日历对象获取出生日期的年,月,日
cal.setTime(birthdayDate);// 修改cal日历对象中的日期为出生日期
// 判断出生日期是否在当前日期之前,如果在之后,就直接返回-1(标识),结束方法
Calendar nowCal = Calendar.getInstance();
if (cal.after(nowCal)) {
return -1;
}
int birthdayYear = cal.get(Calendar.YEAR);
int birthdayMonth = cal.get(Calendar.MONTH);
int birthdayDay = cal.get(Calendar.DAY_OF_MONTH);
// 4.当前的年 - 出生日期的年得到一个初步年龄
int age = nowYear - birthdayYear;
// 5.判断是否有过生日,如果有过生日,初步年龄就是真实年龄;如果没有过生日,初步年龄-1之后就是真实年龄
// 月份没到
if (nowMonth < birthdayMonth) {
age--;
}
// 月份到了,日期没到
if (nowMonth == birthdayMonth) {
if (nowDay < birthdayDay) {
age--;
}
}
// 6.返回年龄
return age;
}
// 2.定义一个方法,用来按照指定格式打印输出集合中的元素内容(学生对象,教师对象)
public static void printArrayList(ArrayList list) {// 不要加泛型,加泛型报错--->?
System.out.println("****************************************************************");
System.out.println("编号\t\t姓名\t\t性别\t\t生日\t\t\t\t年龄\t\t描述");
for (int i = 0; i < list.size(); i++) {
Person p = (Person) list.get(i);
// System.out.println(p.getId() + "\t\t" + p.getName() + "\t\t" + p.getSex() + "\t\t" + p.getBirthday() + "\t\t" + p.getAge() + "\t\t" + p.show());
printPerson(p);
}
System.out.println("****************************************************************");
}
// 3.定义一个方法,用来按照指定格式打印Person对象
public static void printPerson(Person p) {
System.out.println(p.getId() + "\t\t" + p.getName() + "\t\t" + p.getSex() + "\t\t" + p.getBirthday() + "\t\t" + p.getAge() + "\t\t" + p.show());
}
}
public class AppMain {
public static void main(String[] args) throws ParseException {
// ctrl+alt+t
/*while (true) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串的出生日期,格式为yyyy-MM-dd:");
String strBirthday = sc.nextLine();
System.out.println(Utils.birthdayToAge(strBirthday));
}*/
ArrayList<Student> list1 = new ArrayList<>();
list1.add(new Student(1,"张三","男","1999-10-10",18));
list1.add(new Student(2,"张三","男","1999-10-10",18));
Utils.printArrayList(list1);
System.out.println("===============");
ArrayList<Teacher> list2 = new ArrayList<>();
list2.add(new Teacher(1,"李四","男","1999-10-10",18));
list2.add(new Teacher(2,"李四","男","1999-10-10",18));
Utils.printArrayList(list2);
// 编译报错: 因为泛型不存在多态
// ArrayList<Person> list = new ArrayList<Student>();
}
}
第四章 启动类实现
4.1 主菜单
public class AppMain {
public static void main(String[] args) throws ParseException {
// 创建一个学生集合
ArrayList<Student> stuList = new ArrayList<>();
// 创建一个老师集合
ArrayList<Teacher> teaList = new ArrayList<>();
// 创建Scanner对象
Scanner sc = new Scanner(System.in);
// 循环生成一级菜单
while (true){
System.out.println("1. 学生信息管理 2. 教师信息管理 3. 系统退出");
System.out.println("请选择菜单:");
int op = sc.nextInt();
// 根据输入的菜单进入对应的功能
switch (op){
case 1:
// 进入学生信息管理
studentManage(stuList,sc);
break;
case 2:
// 进入教师信息管理
teacherManage(teaList,sc);
break;
case 3:
// 系统退出
System.out.println("谢谢使用,欢迎下次再来!");
System.exit(0);
default:
System.out.println("您输入有误,请重新输入");
break;
}
}
}
// 教室信息管理
private static void teacherManage(ArrayList<Teacher> teaList, Scanner sc) {
}
// 学生信息管理
public static void studentManage(ArrayList<Student> list,Scanner sc){
}
}
4.2 学员信息管理二级菜单
// 学生信息管理
public static void studentManage(ArrayList<Student> list,Scanner sc){
// 循环生成二级菜单
while (true){
System.out.println("----------------------------------------------------------------");
System.out.println("【学生信息管理】");
System.out.println("1.添加学生 2.查询学生 3.修改学生 4.删除学生 5.返回");
System.out.println();
System.out.println("请输入功能序号:");
int op = sc.nextInt();
// 根据输入的功能序号,执行对应的功能
switch (op){
case 1:
// 进入添加学生
addStudent(list,sc);
break;
case 2:
// 进入查询学生
selectStudent(list);
break;
case 3:
// 进入修改学生
updateStudent(list,sc);
break;
case 4:
// 进入删除学生
deleteStudent(list,sc);
break;
case 5:
// 返回到一级菜单
return;
default:
System.out.println("您输入有误,请重新输入!");
break;
}
}
}
// 删除学生
private static void deleteStudent(ArrayList<Student> list, Scanner sc) {
}
// 修改学生
private static void updateStudent(ArrayList<Student> list, Scanner sc) {
}
// 查询学生
private static void selectStudent(ArrayList<Student> list) {
}
// 添加学生
public static void addStudent(ArrayList<Student> list,Scanner sc){
}
4.3 查询所有学员
// 查询学生
private static void selectStudent(ArrayList<Student> list) {
// 判断集合中是否有学生,如果没有,直接结束方法
if (list.size() == 0){
System.out.println("【查询结果】:没有学生信息");
return;
}
// 如果有,就按照指定格式打印输出
Utils.printArrayList(list);
}
4.4 添加学员
// 添加学生
public static void addStudent(ArrayList<Student> list,Scanner sc) throws ParseException {
// 键盘录入学生信息
System.out.println("请输入姓名:");
String name = sc.next();
System.out.println("请输入性别");
String sex = sc.next();
System.out.println("请输入出生日期:");
String birthday = sc.next();
// 创建学生对象
Student stu = new Student();
// 把键盘录入的学生信息赋值给学生对象的属性
Utils.sid++;
stu.setId(Utils.sid);
stu.setName(name);
stu.setSex(sex);
stu.setBirthday(birthday);
// 调用Utils工具类的根据出生日期计算年龄的方法计算年龄
int age = Utils.birthdayToAge(birthday);
stu.setAge(age);
// 把学生对象添加到集合中
list.add(stu);
// 打印提示信息: 添加学生成功
System.out.println("添加学生成功!");
}
4.5 修改学员
// 修改学生
private static void updateStudent(ArrayList<Student> list, Scanner sc) throws ParseException {
// 输入要修改的学生编号 --->2
System.out.println("请输入要修改的学生编号:");
int sid = sc.nextInt();
// 循环遍历list集合
for (int i = 0; i < list.size(); i++) {
// 在循环中,获取遍历出来的学生对象
Student stu = list.get(i);
// 在循环中,判断遍历出来的学生对象的编号是否与输入的学生编号相同
if (stu.getId() == sid) {
// 在循环中,如果相同,就修改,然后结束方法
System.out.println("请输入新的姓名,保留原值请输入0:");
String name = sc.next();
System.out.println("请输入新的性别,保留原值请输入0:");
String sex = sc.next();
System.out.println("请输入新的出生日期,保留原值请输入0:");
String birthday = sc.next();
// 判断输入的值是否为0,如果不为0就修改,如果为0就不修改
if (!"0".equals(name)) {
// 修改
stu.setName(name);
}
if (!"0".equals(sex)) {
stu.setSex(sex);
}
if (!"0".equals(birthday)) {
stu.setBirthday(birthday);
// 重新计算新的年龄
int age = Utils.birthdayToAge(birthday);
stu.setAge(age);
}
System.out.println("【结果】:恭喜您,修改成功!");
return;
}
}
// 循环结束后,提示修改失败的信息!
System.out.println("【错误】ID: " + sid + " 不存在,修改失败!");
}
4.6 删除学员
// 删除学生
private static void deleteStudent(ArrayList<Student> list, Scanner sc) {
// 键盘录入要删除的学生编号
System.out.println("请输入要删除的学生编号:");
int sid = sc.nextInt();
// 循环遍历list集合
for (int i = 0; i < list.size(); i++) {
// 在循环中,获取遍历出来的学生对象
Student stu = list.get(i);
// 在循环中,判断遍历出来的学生对象的编号是否与要删除的学生编号相同
if (stu.getId() == sid) {
// 在循环中,如果相同,就删除,结束方法
System.out.println("【您要删除的学生信息如下:】");
System.out.println("****************************************************************");
System.out.println("编号\t\t姓名\t\t性别\t\t生日\t\t\t\t年龄\t\t描述");
// 按照指定格式打印学生对象的信息
Utils.printPerson(stu);
System.out.println("****************************************************************");
while (true) {
System.out.println("【确认】您确定要删除这条信息吗?(y/n)");
// 键盘录入确认删除信息:
String confirm = sc.next();//
// 判断确认信息
if ("y".equalsIgnoreCase(confirm)) {
// 删除
list.remove(i);
System.out.println("【删除成功】");
break;
} else if ("n".equalsIgnoreCase(confirm)) {
// 取消删除
System.out.println("【删除操作取消】");
break;
} else {
System.out.println("您输入的有误,请重新输入!");
}
}
return;
}
}
// 循环结束后,提示删除失败的信息!
System.out.println("【错误】ID: " + sid + " 不存在,删除失败!");
}
总结
必须练习:
1.类的设计---->Person类使用模板设计
2.测试类中的修改和删除的功能必须要练习
3.工具类中的打印集合和打印Person对象的方法必须练习
4.根据出生日期计算年龄---->锻炼日期相关类的方法
- 能够编写主菜单
死循环生成主菜单,具体步骤查看第四章启动类实现的主菜单
- 能够定义Person类并应用模板模式
抽象父类, show方法定义为了通用模板,getType,getWork定义为了填充模板
- 能够定义子类Student类并添加特有成员
继承Person类,重写getType,getWork
- 能够定义子类Teacher类并添加特有成员
继承Person类,重写getType,getWork
- 能够理解继承在案例中的使用
Student,Teacher继承Person
- 能够理解模板模式在案例中的使用
Person类应用模板模式
- 能够定义并使用打印Person的静态方法
// 形参多态
public static void printPerson(Person p) {
System.out.println(p.getId() + "\t\t" + p.getName() + "\t\t" + p.getSex() + "\t\t" + p.getBirthday() + "\t\t" + p.getAge() + "\t\t" + p.show());
}
- 能够定义并使用打印ArrayList的静态方法
public static void printArrayList(ArrayList list) {// 不要加泛型,加泛型报错 System.out.println("****************************************************************");
System.out.println("编号\t\t姓名\t\t性别\t\t生日\t\t\t\t年龄\t\t描述");
for (int i = 0; i < list.size(); i++) {
Person p = (Person)list.get(i);
p.getId();
// System.out.println(p.getId() + "\t\t" + p.getName() + "\t\t" + p.getSex() + "\t\t" + p.getBirthday() + "\t\t" + p.getAge() + "\t\t" + p.show());
printPerson(p);
}
System.out.println("****************************************************************");
}
- 能够理解静态成员变量和静态方法在案例中的使用
实现学生编号\老师编号自增: 静态成员变量在内存中只有一份,被共享
静态方法: 工具类中的根据出生日期计算年龄,按照指定格式打印集合或者Person对象