今日内容
- 面向对象综合练习
教学目标
- 能够编写主菜单
- 能够定义Person类并应用模板模式
- 能够定义子类Student类并添加特有成员
- 能够定义子类Teacher类并添加特有成员
- 能够理解继承在案例中的使用
- 能够理解模板模式在案例中的使用
- 能够定义并使用打印Person的静态方法
- 能够定义并使用打印ArrayList的静态方法
- 能够理解静态成员和静态方法在案例中的使用
第一章 综合案例-案例演示
1.1 程序启动
运行com.itheima.main.MainApp类,启动程序:
显示项目的一级菜单:
1.2 测试学员信息管理模块
显示项目的二级菜单:学员信息管理模块。
1.3 测试【4.查询学员】
1.4 测试【1.添加学员】
1.5 测试【2.修改学员】
- 输入不存在的编号:
- 输入存在的编号:
1.6 测试【3.删除学员】
- 输入不存在的编号:
- 输入存在的编号:
小结:
1.学生编号不用输入,是自动累加生成的
2.学生年龄是根据输入的生日计算出来的
3.案例流程图:
第二章 综合案例-类设计
2.1 父类Person(抽象)
-
成员属性:
- id(编号)
- name(姓名)
- sex(性别)
- birthday(生日)
- age(年龄-由生日计算得出)
-
构造方法:
- 无参构造
- 全参构造
-
成员方法:
- toString()
-
抽象方法:
- String getType():由各子类实现,返回各自的"类型"字符串。
- String getWork():由各子类实现,返回各自的"工作"字符串。
代码演示:
package com.itheima.domain;
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;
}
//成员方法
//getType() 职业
public abstract String getType();
//getWork() 工作
public abstract String getWork();
}
2.2 子类Student
- 构造方法
- 无参构造
- 全参构造(super调用父类全参构造)
- 重写抽象方法
- 重写getType()
- 重写getWork()
代码演示:
package com.itheima.domain;
//实体类
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";
}
}
2.3 子类Teacher
- 构造方法
- 无参构造
- 全参构造(super调用父类全参构造)
- 重写抽象方法
- 重写getType()
- 重写getWork()
代码实现:
public class Teacher extends Person {
public Teacher() {
}
public Teacher(int id, String name, String sex, String birthday) {
super(id, name, sex, birthday);
}
@Override
public String getWork() {
return "讲课";
}
@Override
public String getType() {
return "老师";
}
}
2.4 工具类Utils类
- 全局变量
- 学员ID值(添加学员信息时,编号由此ID加1生成)
- 教师ID值(添加教师信息时,编号由此ID加1生成)
- 全局方法
- 根据生日计算年龄的方法
- 打印一个ArrayList集合的方法;
import com.itheima.domain.Person;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
public class Utils {
public static int stuId = 0;//学员ID的初始值 后期可以改为从文件/数据库读取初始值
public static int teaId = 0;//教师ID的初始值
//通过生日计算年龄
public static int birthdayToAge(String birthday) {//"1999-11-13"
Date birthDate = null;
//异常处理的代码,后边学
//这个东西以后讲(idea生成就可以了)
try {
birthDate =new SimpleDateFormat("yyyy-MM-dd").parse(birthday);
} catch (ParseException e) {
e.printStackTrace();
}
//获取当前系统时间
Calendar now = Calendar.getInstance();
//如果出生日期大于当前时间,则抛出异常
Calendar birth = Calendar.getInstance();//获取当前日期的Calendar
//将birthDate表示生日日期转换为Calendar
birth.setTime(birthDate);//将生日转换为Calendar(1999-11-13)
//2020 2030
// boolean before(Object when) 判断此 Calendar 表示的时间是否在指定 Object 表示的时间之 前,返回判断结果。
//这里就是判断now表示的时间是否在参数birth的时间之前,如果是返回true
//举例:当前时间:2020 出生日期填写2030 那么显然是非法的,那么before方法就会返回true
if (now.before(birth)) {//判断当前日期是否在生日日期之前(before()的参数必须是一个Calendar类型)
return -1;//表示计算失败
}
//取出系统当前时间的年、月、日部分
int yearNow = now.get(Calendar.YEAR);
int monthNow = now.get(Calendar.MONTH);
int day = now.get(Calendar.DAY_OF_MONTH);
//取出出生日期的年、月、日部分
int yearBirth = birth.get(Calendar.YEAR);
int monthBirth = birth.get(Calendar.MONTH);
int dayBirth = birth.get(Calendar.DAY_OF_MONTH);
//当前年份与出生年份相减,初步计算年龄
// 21 2020 1999
int age = yearNow - yearBirth;
//当前月份与出生日期的月份相比,如果月份小于出生月份,则年龄上减1,表示不满多少周岁
if (monthNow < monthBirth) {
age--;
}
//如果月份相等,在比较日期,如果当前日,小于出生日,也减1,表示不满多少周岁
// 1999-3-20 1999-3-30
if (monthNow == monthBirth && day < dayBirth) {//如果:当前月 = 生日月
age--;
}
return age;
}
//打印ArrayList的方法
public static void printPersonList(ArrayList<? extends Person> 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 = 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.getType() +"我要" + p.getWork());
}
System.out.println("************************************************************************************");
}
}
第三章 综合案例-启动类实现
3.1 主菜单(一级菜单)
package com.itheima.run;
import com.itheima.domain.Student;
import java.util.ArrayList;
import java.util.Scanner;
public class MainApp {
//一级菜单
public static void main(String[] args) {
//定义集合保存学员信息
//在这里定义才能保证是一个唯一的集合
ArrayList<Student> list = new ArrayList<>();
//教师集合
//ArrayList<Teacher> teaList = new ArrayList<>();
Scanner sc = new Scanner(System.in);
//0.死循环
while(true) {
//1.给用户展示选项
System.out.println("***************************************");
System.out.println("1.学员信息管理 2.教师信息管理 3.退出");
System.out.println("***************************************");
//2.键盘输入
System.out.println("请输入菜单编号:");
int choose = sc.nextInt();
//输入String或者输入Double或者写default这都不是重点,以后开发中不会有这些问题。
//3.做判断
switch (choose){
case 1:
//学生管理系统
StudentManager.manager(list);
break;
case 2:
//教师管理系统
break;
case 3:
//退出系统
System.exit(0);
default:
System.out.println("输入错误");
}
}
}
}
3.2 学员信息管理二级菜单
//学生系统
public class StudentManager {
//二级菜单
public static void manager(ArrayList<Student> list){
//0.死循环
while(true) {
//1.展示信息
System.out.println("=====================================================");
System.out.println("【学员信息管理】");
System.out.println();
System.out.println("1.添加学员 2.修改学员 3.查询学员 4.删除学员 5.返回");
System.out.println("=====================================================");
//2.用户键盘录入
Scanner sc = new Scanner(System.in);
System.out.println("请输入菜单编号:");
int choose = sc.nextInt();
//3.判断
switch (choose){
case 1:
//添加学员
addStudent(list);
break;
case 2:
//修改学员
updateStudent(list);
break;
case 3:
//查询学员
findStudent(list);
break;
case 4:
//删除学员
deleteStudent(list);
break;
case 5:
//返回
//return是结束当前方法,结束了方法就结束了本次二级菜单,返回到一级菜单中,这里不能使用System.exit(0);停止jvm虚拟机
return;
default:
System.out.println("输入错误");
}
}
}
}
3.3 添加学员
//添加方法
private static void addStudent(ArrayList<Student> list) {
//1.让用户输入姓名/性别/生日
Scanner sc = new Scanner(System.in);
System.out.println("请输入学员姓名:");
String name = sc.next();
System.out.println("请输入学员性别:");
String sex = sc.next();
System.out.println("请输入学员出生日期:(2000-01-01)");
String birthday = sc.next();
//编号
Utils.stuId++;
//年龄
int age = Utils.birthdayToAge(birthday);
//2.把信息封装成学生对象
Student stu = new Student(Utils.stuId,name,sex,birthday,age);
//3.把学生对象保存到集合中
list.add(stu);
//4.给用户添加成功的提醒
System.out.println("【添加成功】");
}
3.4 查询所有学员
//查看学员信息
private static void findStudent(ArrayList<Student> list) {
//1.没有学员 提醒没有学员无法查看
if(list.size() == 0){
//没有学员
System.out.println("【目前没有学员】");
}else {
//2.有学员
Utils.printPersonList(list);
}
}
3.5 修改学员
//修改学员
private static void updateStudent(ArrayList<Student> list) {
//1.让用户输入要修改的编号
Scanner sc = new Scanner(System.in);
System.out.println("请输入要修改的学员的编号:");
int id = sc.nextInt();
//2.判断集合中是否存在这个编号
for (int i = 0; i < list.size(); i++) {
//获取集合中的学生
Student stu = list.get(i);
//获取学生的编号
int id1 = stu.getId();
//判断
if(id == id1){
//3.如果存在
//就让用户继续输入姓名/性别/生日
System.out.println("请输入新的学员姓名:(保留原值请输入0)");
String name = sc.next(); //next()输入字符串不会和nextInt()出现冲突
System.out.println("请输入新的学员性别:(保留原值请输入0)");
String sex = sc.next();
System.out.println("请输入新的学员生日:(保留原值请输入0)");
String birthday = sc.next();
//把新的值赋值给学生对象
//if(name != "0"){ String是引用类型 千万不要使用 == 和 != 做判断
if(!name.equals("0")){
stu.setName(name);
}
if(!sex.equals("0")){
stu.setSex(sex);
}
if(!birthday.equals("0")){
stu.setBirthday(birthday);
//生日如果改变年龄也要改变
int age = Utils.birthdayToAge(birthday);
stu.setAge(age);
}
// 完成修改 【修改成功】
System.out.println("【修改成功】");
// 结束方法
return;
}
}
//如果循环结束之后都找不到这个编号才说明不存在
//4.如果不存在 【你输入的编号不存在】
System.out.println("【你输入的编号不存在】");
}
3.6 删除学员
//删除学员
private static void deleteStudent(ArrayList<Student> list) {
//1.让用户输入要删除的编号
Scanner sc = new Scanner(System.in);
System.out.println("请输入要删除的学员的编号:");
int id = sc.nextInt();
//2.判断集合中是否存在这个编号
for (int i = 0; i < list.size(); i++) {
//获取学生对象
Student stu = list.get(i);
//获取学生的编号
int id1 = stu.getId();
//判断
//3.如果存在就删除【删除成功】
if(id == id1) {
//集合有这个编号 删除
list.remove(i);
//给用户一个提示
System.out.println("【删除成功】");
//结束方法
return;
}
}
//如果循环结束之后都找不到这个编号才说明不存在
//4.如果不存在就告诉用户【你输入的编号有误】
System.out.println("【你输入的编号有误】");
}