继承关系可以实现对象类型转换 将父类转换成子类,使用独有方法
sdf.parse(str) 是将字符串解析成日期方法 (属于 SimpleDateFormat类)
package com.itheima.run;
import com.itheima.bean.Business;
import com.itheima.bean.Customer;
import com.itheima.bean.Movie;
import com.itheima.bean.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.naming.NamingEnumeration;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class MovieSystem {
/**
* 定义系统的数据容器用户存储数据
* 1. 存储很多用户(客户对象,商家对象)
*/
// 定义成一个常量集合,表示这个集合容器不能被改变(地址不能变,可以加数据,地址永远指向ArrayList
public static final List<User> ALL_USERS = new ArrayList<>(); // 这里用List存储,也可以用Set集合,只不过顺序是无序的
/**
* 存储系统全部商家和 其排片信息
* 商家1 = 【p1,p2,p3...]
* 商家2 = 【p2,p3,...]
* 。。。。 使用map集合,键值对的形式
* @param args
*/
public static final Map<Business,List<Movie>> ALL_MOVIES = new HashMap<>(); // 经典的Map集合写法代码
// 定义一个静态常量的扫描器,防止别人修改(加final修饰)
public static final Scanner SYS_SC = new Scanner(System.in);
// 定义一个静态的User类型的变量记住当前登录成功的用户类型
// 一开始没有记住用户,这个变量加载一次
// 静态变量成员 (共享的,在本类中直接调用变量名即可)
public static User loginUser; // 这是一个静态的变量,每次登录一个用户,就传给这个变量
// 定义一个静态常量的(简单日期格式化对象)SimpleDateFormat sdf
public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 定义一个日志对象
public static final Logger LOGGER = LoggerFactory.getLogger("MovieSystem.class"); // 当前类里面打印日志
/**
* 3. 准备一些测试数据
* @param args
*/
static {
// Customer 是自己定义的用户类(继承了User类),为成员添加值
// 可以继承父类的私有成员,不能直接访问,但是可以通过geter,seter访问
// 然后将 用户对象,添加到集合中去 c对象有LoginName等成员且被重新赋值,不能直接访问
// 然后将 用户对象,添加到集合中去
// 因为Business类继承了User类, 作为子类对象可以扔进去(ALL_USERS集合接收的是父类对象,子类也可以进去)
// 然后将 用户对象,添加到集合中去
// 注意: 商家一定需要加入到店铺排片信息中去
// 键值对形式 {商家:电影名) // b = []
Customer c = new Customer();
c.setLoginName("zyf888");
c.setPassWord("123456");
c.setUserName("黑马刘德华");
c.setSex('男');
c.setMoney(10000);
c.setPhone("110110");
ALL_USERS.add(c);
Customer c1 = new Customer();
c1.setLoginName("gzl888");
c1.setPassWord("123456");
c1.setUserName("黑马关之琳");
c1.setSex('女');
c1.setMoney(2000);
c1.setPhone("111111");
ALL_USERS.add(c1);
Business b = new Business();
b.setLoginName("baozugong888");
b.setPassWord("123456");
b.setUserName("黑马包租公");
b.setMoney(0);
b.setSex('男');
b.setPhone("110110");
b.setAddress("火星6号2B二层");
b.setShopName("甜甜圈国际影城");
ALL_USERS.add(b);
// 注意,商家一定需要加入到店铺排片信息中去
List<Movie> movies = new ArrayList<>();
ALL_MOVIES.put(b , movies); // b = []
Business b2 = new Business();
b2.setLoginName("baozupo888");
b2.setPassWord("123456");
b2.setUserName("黑马包租婆");
b2.setMoney(0);
b2.setSex('女');
b2.setPhone("110110");
b2.setAddress("火星8号8B八层");
b2.setShopName("巧克力国际影城");
ALL_USERS.add(b2);
// 注意,商家一定需要加入到店铺排片信息中去
List<Movie> movies3 = new ArrayList<>();
ALL_MOVIES.put(b2 , movies3); // b2 = []
}
public static void main(String[] args) {
// 将首页展示定义成一个方法,然后调用就可以了
showMain();
}
private static void showMain() {
while (true) {
System.out.println("==========黑马电影首页============");
System.out.println("1. 登录");
System.out.println("2. 用户注册");
System.out.println("3. 商家注册");
System.out.println("请输入操作命令:");
// 使用扫描器的API nextLine 扫描一行的数据, next是扫描输入的数据,但是遇到空格会停止扫描,nextLine扫描一整行
String command = SYS_SC.nextLine();
// 用switch分支,当用户输入对应的数字命令,会跳到对应的分支里面去
switch (command){
case "1":
// 登录了 (像这种要定义独立功能的,要写独立方法)
login();
break;
case "2":
break;
case "3":
break;
case "4":
break;
default:
System.out.println("命令有误,请确认!");
}
}
}
private static void login() {
while (true) {
System.out.println("请您输入登录名称:");
String loginName = SYS_SC.nextLine();
System.out.println("请您输入登录密码:");
String passWord = SYS_SC.nextLine();
// 1. 根据登录名称查询用户对象
User u = getUserByLoginName(loginName); // 在这里传入用户名
// 2. 判断用户对象是否存在,存在则说明登录名称正确
if (u != null){ // 像这种一直要判断的,要定义死循环
// 如果该用户不为空,说明存在,存在说明登录名称正确了
// 登录名称正确要验证密码是否正确
if (u.getPassWord().equals(passWord)){
// 登录成功
// 登录成功后将这个对象 传给 先前创建的静态变量
loginUser = u;
// 打印日志log
LOGGER.info(u.getUserName() + "登录了系统~~");
// 判断是用户登录的,还是商家登录的 instanceof是判断对象类型
if (u instanceof Customer){ // 判断出如果是客户对象
// 当前登录的是普通用户
showCustomerMain();
}else {
// 当前用户肯定是商家用户(因为User类就存储了两种继承子类对象)
showBusinessMain();
}
return; // 判断出用户登录后登录成功结束该方法
}else {
System.out.println("密码有毛病 ");
}
}else {
System.out.println("登录名称错误,请确认");
}
}
}
private static void showBusinessMain() {
while (true) {
System.out.println("============黑马电影商家界面===================");
// 获取当前登录对象的用户名
System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生": "女生" + "欢迎来到该系统"));
System.out.println("1、展示详情:");
System.out.println("2、上架电影:");
System.out.println("3、下架电影:");
System.out.println("4、修改电影:");
System.out.println("5、退出:");
System.out.println("请输入您要操作的命令:");
String command = SYS_SC.nextLine();
switch (command){
case "1":
// 展示全部排片信息
showBusinessInfos();
break;
case "2":
// 上架电影信息
addMovie();
break;
case "3":
// 下架电影信息
break;
case "4":
// 修改电影信息
break;
case "5":
System.out.println(loginUser.getUserName() + "请您下次再来");
return; // 干掉方法
default:
System.out.println("不存在该命令!!");
break;
}
}
}
/**
* 商家进行电影上架
* Map<Business , List<Movie>> ALL_MOVIES
* u1 = [p1,p2,p3]
* u2 = [p1,p2,p3]
*/
private static void addMovie() {
// 根据商家对象(就是登录的用户loginUser),作为Map集合的键 提取对应的值就是其排片信息:Map<Business, List<Movie>> ALL_MOVIES
// 继承关系可以实现对象类型转换 将父类转换成子类,使用独有方法
Business business = (Business) loginUser; // 将对象进行转换(loginUser的类型是属于User类的对象,转换成子类)
List<Movie> movies = ALL_MOVIES.get(business); // 获取键business用户的值,影片集合
System.out.println("请您输入新片名:");
String name = SYS_SC.nextLine();
System.out.println("请您输入主演:");
String actor = SYS_SC.nextLine();
System.out.println("请您输入时长:");
String time = SYS_SC.nextLine();
System.out.println("请您输入票价:");
String price = SYS_SC.nextLine();
System.out.println("请您输入票数:");
String totalNumber = SYS_SC.nextLine(); // 200\n
while (true) {
try {
System.out.println("请您输入影片放映时间:"); // 因为这里日期时间容易输入错误,所以将他放入异常处理try中
String stime = SYS_SC.nextLine();
// public Movie(String name, String actor, double time, double price,
// int number, Date startTime) // 封装成电影对象 ,加入集合movices中去
Movie movie = new Movie(name, actor ,Double.valueOf(time) , Double.valueOf(price)
, Integer.valueOf(totalNumber) , sdf.parse(stime)); // 字符串先解析成日期对象
movies.add(movie);
System.out.println("您已经成功上架了:《" + movie.getName() + "》 ");
return; // 上架后,结束方法
} catch (ParseException e) {
e.printStackTrace();
// 打印日志对象
LOGGER.error("时间解析出了毛病"); // 这里最好定义一个死循环,当程序进入catch时(就是异常了,再次让用户输入放映时间
}
}
}
/**
* 展示当前商家的信息
*/
private static void showBusinessInfos(){
System.out.println("=============商家详情界面=====================");
LOGGER.info(loginUser.getUserName() + "商家正在看自己的详情"); // 打印商家用户名的日志
// 根据商家对象(就是登录的用户loginUser),作为Map集合的键 提取对应的值就是其排片信息:Map<Business, List<Movie>> ALL_MOVIES
// 登录的用户确实是商家对象,但是loginUser的类型是User父类类型,要用子类的独有方法,要转换对象类型
Business business = (Business) loginUser; // 转换称商家类型,就可以调用其子类的独有方法
System.out.println(business.getShopName() + "\t\t 电话:" + business.getPhone() + "\t\t地址:" + business.getAddress()); // \t是空两格
// 这个是map集合的get方法,根据键获取值, 根据商家对象Business对象,获取该对应的movies影片
List<Movie> movies = ALL_MOVIES.get(loginUser); // 这是拿到排片信息(存储movie对象的集合movies)自定义的movie
System.out.println("片名\t\t\t主演\t\t时长\t\t评分\t\t票价\t\t余票数量\t\t放映时间");
if (movies.size() > 0){ // 当影片的大小大于0部的时候
for (Movie movie : movies) {
// 遍历所有影片信息
System.out.println(movie.getName()+"\t\t\t" + movie.getActor() + "\t\t\t" + movie.getTime()
+ "\t\t"+ movie.getScore() + "\t\t" + movie.getPrice() + "\t\t" + movie.getNumber() + "\t\t"
+ sdf.format(movie.getStartTime()) ); // 格式化,上映时间
}
}else { // 小于0部,证明没有片子上映
System.out.println("您的店铺当前无片放映");
}
}
private static void showCustomerMain() {
while (true) {
System.out.println("============黑马电影客户界面===================");
System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生": "女生" + "欢迎来到该系统"));
System.out.println("请您选择要操作的功能:");
System.out.println("1、展示全部影片信息功能:");
System.out.println("2、根据电影名称查询电影信息:");
System.out.println("3、评分功能:");
System.out.println("4、购票功能:");
System.out.println("5、退出系统:");
System.out.println("请输入您要操作的命令:");
String command = SYS_SC.nextLine();
switch (command){
case "1":
// 展示全部排片信息
break;
case "2":
break;
case "3":
// 评分功能
break;
case "4":
// 购票功能
break;
case "5":
return; // 干掉方法
default:
System.out.println("不存在该命令!!");
break;
}
}
}
// 定义一个搜索用户名的方法 getUserByLoginName
public static User getUserByLoginName (String loginName) {
// 遍历用户集合的每个元素ALL_USERS
for (User user : ALL_USERS) { // 遍历出来的都是存储在User类的对象
// 判断这个用户的登录名称是否是我们想要的
if (user.getLoginName().equals(loginName)){
// 判断用户的登录名是否和搜索的登录名是否一样
return user; // 如果一样,返回该用户对象,代表查到了
}
}
return null; // 否则就没查到,结束方法
}
}