image.png
    继承关系可以实现对象类型转换 将父类转换成子类,使用独有方法
    image.png
    sdf.parse(str) 是将字符串解析成日期方法 (属于 SimpleDateFormat类)

    1. package com.itheima.run;
    2. import com.itheima.bean.Business;
    3. import com.itheima.bean.Customer;
    4. import com.itheima.bean.Movie;
    5. import com.itheima.bean.User;
    6. import org.slf4j.Logger;
    7. import org.slf4j.LoggerFactory;
    8. import javax.naming.NamingEnumeration;
    9. import java.text.ParseException;
    10. import java.text.SimpleDateFormat;
    11. import java.util.*;
    12. public class MovieSystem {
    13. /**
    14. * 定义系统的数据容器用户存储数据
    15. * 1. 存储很多用户(客户对象,商家对象)
    16. */
    17. // 定义成一个常量集合,表示这个集合容器不能被改变(地址不能变,可以加数据,地址永远指向ArrayList
    18. public static final List<User> ALL_USERS = new ArrayList<>(); // 这里用List存储,也可以用Set集合,只不过顺序是无序的
    19. /**
    20. * 存储系统全部商家和 其排片信息
    21. * 商家1 = 【p1,p2,p3...]
    22. * 商家2 = 【p2,p3,...]
    23. * 。。。。 使用map集合,键值对的形式
    24. * @param args
    25. */
    26. public static final Map<Business,List<Movie>> ALL_MOVIES = new HashMap<>(); // 经典的Map集合写法代码
    27. // 定义一个静态常量的扫描器,防止别人修改(加final修饰)
    28. public static final Scanner SYS_SC = new Scanner(System.in);
    29. // 定义一个静态的User类型的变量记住当前登录成功的用户类型
    30. // 一开始没有记住用户,这个变量加载一次
    31. // 静态变量成员 (共享的,在本类中直接调用变量名即可)
    32. public static User loginUser; // 这是一个静态的变量,每次登录一个用户,就传给这个变量
    33. // 定义一个静态常量的(简单日期格式化对象)SimpleDateFormat sdf
    34. public static SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
    35. // 定义一个日志对象
    36. public static final Logger LOGGER = LoggerFactory.getLogger("MovieSystem.class"); // 当前类里面打印日志
    37. /**
    38. * 3. 准备一些测试数据
    39. * @param args
    40. */
    41. static {
    42. // Customer 是自己定义的用户类(继承了User类),为成员添加值
    43. // 可以继承父类的私有成员,不能直接访问,但是可以通过geter,seter访问
    44. // 然后将 用户对象,添加到集合中去 c对象有LoginName等成员且被重新赋值,不能直接访问
    45. // 然后将 用户对象,添加到集合中去
    46. // 因为Business类继承了User类, 作为子类对象可以扔进去(ALL_USERS集合接收的是父类对象,子类也可以进去)
    47. // 然后将 用户对象,添加到集合中去
    48. // 注意: 商家一定需要加入到店铺排片信息中去
    49. // 键值对形式 {商家:电影名) // b = []
    50. Customer c = new Customer();
    51. c.setLoginName("zyf888");
    52. c.setPassWord("123456");
    53. c.setUserName("黑马刘德华");
    54. c.setSex('男');
    55. c.setMoney(10000);
    56. c.setPhone("110110");
    57. ALL_USERS.add(c);
    58. Customer c1 = new Customer();
    59. c1.setLoginName("gzl888");
    60. c1.setPassWord("123456");
    61. c1.setUserName("黑马关之琳");
    62. c1.setSex('女');
    63. c1.setMoney(2000);
    64. c1.setPhone("111111");
    65. ALL_USERS.add(c1);
    66. Business b = new Business();
    67. b.setLoginName("baozugong888");
    68. b.setPassWord("123456");
    69. b.setUserName("黑马包租公");
    70. b.setMoney(0);
    71. b.setSex('男');
    72. b.setPhone("110110");
    73. b.setAddress("火星6号2B二层");
    74. b.setShopName("甜甜圈国际影城");
    75. ALL_USERS.add(b);
    76. // 注意,商家一定需要加入到店铺排片信息中去
    77. List<Movie> movies = new ArrayList<>();
    78. ALL_MOVIES.put(b , movies); // b = []
    79. Business b2 = new Business();
    80. b2.setLoginName("baozupo888");
    81. b2.setPassWord("123456");
    82. b2.setUserName("黑马包租婆");
    83. b2.setMoney(0);
    84. b2.setSex('女');
    85. b2.setPhone("110110");
    86. b2.setAddress("火星8号8B八层");
    87. b2.setShopName("巧克力国际影城");
    88. ALL_USERS.add(b2);
    89. // 注意,商家一定需要加入到店铺排片信息中去
    90. List<Movie> movies3 = new ArrayList<>();
    91. ALL_MOVIES.put(b2 , movies3); // b2 = []
    92. }
    93. public static void main(String[] args) {
    94. // 将首页展示定义成一个方法,然后调用就可以了
    95. showMain();
    96. }
    97. private static void showMain() {
    98. while (true) {
    99. System.out.println("==========黑马电影首页============");
    100. System.out.println("1. 登录");
    101. System.out.println("2. 用户注册");
    102. System.out.println("3. 商家注册");
    103. System.out.println("请输入操作命令:");
    104. // 使用扫描器的API nextLine 扫描一行的数据, next是扫描输入的数据,但是遇到空格会停止扫描,nextLine扫描一整行
    105. String command = SYS_SC.nextLine();
    106. // 用switch分支,当用户输入对应的数字命令,会跳到对应的分支里面去
    107. switch (command){
    108. case "1":
    109. // 登录了 (像这种要定义独立功能的,要写独立方法)
    110. login();
    111. break;
    112. case "2":
    113. break;
    114. case "3":
    115. break;
    116. case "4":
    117. break;
    118. default:
    119. System.out.println("命令有误,请确认!");
    120. }
    121. }
    122. }
    123. private static void login() {
    124. while (true) {
    125. System.out.println("请您输入登录名称:");
    126. String loginName = SYS_SC.nextLine();
    127. System.out.println("请您输入登录密码:");
    128. String passWord = SYS_SC.nextLine();
    129. // 1. 根据登录名称查询用户对象
    130. User u = getUserByLoginName(loginName); // 在这里传入用户名
    131. // 2. 判断用户对象是否存在,存在则说明登录名称正确
    132. if (u != null){ // 像这种一直要判断的,要定义死循环
    133. // 如果该用户不为空,说明存在,存在说明登录名称正确了
    134. // 登录名称正确要验证密码是否正确
    135. if (u.getPassWord().equals(passWord)){
    136. // 登录成功
    137. // 登录成功后将这个对象 传给 先前创建的静态变量
    138. loginUser = u;
    139. // 打印日志log
    140. LOGGER.info(u.getUserName() + "登录了系统~~");
    141. // 判断是用户登录的,还是商家登录的 instanceof是判断对象类型
    142. if (u instanceof Customer){ // 判断出如果是客户对象
    143. // 当前登录的是普通用户
    144. showCustomerMain();
    145. }else {
    146. // 当前用户肯定是商家用户(因为User类就存储了两种继承子类对象)
    147. showBusinessMain();
    148. }
    149. return; // 判断出用户登录后登录成功结束该方法
    150. }else {
    151. System.out.println("密码有毛病 ");
    152. }
    153. }else {
    154. System.out.println("登录名称错误,请确认");
    155. }
    156. }
    157. }
    158. private static void showBusinessMain() {
    159. while (true) {
    160. System.out.println("============黑马电影商家界面===================");
    161. // 获取当前登录对象的用户名
    162. System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生": "女生" + "欢迎来到该系统"));
    163. System.out.println("1、展示详情:");
    164. System.out.println("2、上架电影:");
    165. System.out.println("3、下架电影:");
    166. System.out.println("4、修改电影:");
    167. System.out.println("5、退出:");
    168. System.out.println("请输入您要操作的命令:");
    169. String command = SYS_SC.nextLine();
    170. switch (command){
    171. case "1":
    172. // 展示全部排片信息
    173. showBusinessInfos();
    174. break;
    175. case "2":
    176. // 上架电影信息
    177. addMovie();
    178. break;
    179. case "3":
    180. // 下架电影信息
    181. break;
    182. case "4":
    183. // 修改电影信息
    184. break;
    185. case "5":
    186. System.out.println(loginUser.getUserName() + "请您下次再来");
    187. return; // 干掉方法
    188. default:
    189. System.out.println("不存在该命令!!");
    190. break;
    191. }
    192. }
    193. }
    194. /**
    195. * 商家进行电影上架
    196. * Map<Business , List<Movie>> ALL_MOVIES
    197. * u1 = [p1,p2,p3]
    198. * u2 = [p1,p2,p3]
    199. */
    200. private static void addMovie() {
    201. // 根据商家对象(就是登录的用户loginUser),作为Map集合的键 提取对应的值就是其排片信息:Map<Business, List<Movie>> ALL_MOVIES
    202. // 继承关系可以实现对象类型转换 将父类转换成子类,使用独有方法
    203. Business business = (Business) loginUser; // 将对象进行转换(loginUser的类型是属于User类的对象,转换成子类)
    204. List<Movie> movies = ALL_MOVIES.get(business); // 获取键business用户的值,影片集合
    205. System.out.println("请您输入新片名:");
    206. String name = SYS_SC.nextLine();
    207. System.out.println("请您输入主演:");
    208. String actor = SYS_SC.nextLine();
    209. System.out.println("请您输入时长:");
    210. String time = SYS_SC.nextLine();
    211. System.out.println("请您输入票价:");
    212. String price = SYS_SC.nextLine();
    213. System.out.println("请您输入票数:");
    214. String totalNumber = SYS_SC.nextLine(); // 200\n
    215. while (true) {
    216. try {
    217. System.out.println("请您输入影片放映时间:"); // 因为这里日期时间容易输入错误,所以将他放入异常处理try中
    218. String stime = SYS_SC.nextLine();
    219. // public Movie(String name, String actor, double time, double price,
    220. // int number, Date startTime) // 封装成电影对象 ,加入集合movices中去
    221. Movie movie = new Movie(name, actor ,Double.valueOf(time) , Double.valueOf(price)
    222. , Integer.valueOf(totalNumber) , sdf.parse(stime)); // 字符串先解析成日期对象
    223. movies.add(movie);
    224. System.out.println("您已经成功上架了:《" + movie.getName() + "》 ");
    225. return; // 上架后,结束方法
    226. } catch (ParseException e) {
    227. e.printStackTrace();
    228. // 打印日志对象
    229. LOGGER.error("时间解析出了毛病"); // 这里最好定义一个死循环,当程序进入catch时(就是异常了,再次让用户输入放映时间
    230. }
    231. }
    232. }
    233. /**
    234. * 展示当前商家的信息
    235. */
    236. private static void showBusinessInfos(){
    237. System.out.println("=============商家详情界面=====================");
    238. LOGGER.info(loginUser.getUserName() + "商家正在看自己的详情"); // 打印商家用户名的日志
    239. // 根据商家对象(就是登录的用户loginUser),作为Map集合的键 提取对应的值就是其排片信息:Map<Business, List<Movie>> ALL_MOVIES
    240. // 登录的用户确实是商家对象,但是loginUser的类型是User父类类型,要用子类的独有方法,要转换对象类型
    241. Business business = (Business) loginUser; // 转换称商家类型,就可以调用其子类的独有方法
    242. System.out.println(business.getShopName() + "\t\t 电话:" + business.getPhone() + "\t\t地址:" + business.getAddress()); // \t是空两格
    243. // 这个是map集合的get方法,根据键获取值, 根据商家对象Business对象,获取该对应的movies影片
    244. List<Movie> movies = ALL_MOVIES.get(loginUser); // 这是拿到排片信息(存储movie对象的集合movies)自定义的movie
    245. System.out.println("片名\t\t\t主演\t\t时长\t\t评分\t\t票价\t\t余票数量\t\t放映时间");
    246. if (movies.size() > 0){ // 当影片的大小大于0部的时候
    247. for (Movie movie : movies) {
    248. // 遍历所有影片信息
    249. System.out.println(movie.getName()+"\t\t\t" + movie.getActor() + "\t\t\t" + movie.getTime()
    250. + "\t\t"+ movie.getScore() + "\t\t" + movie.getPrice() + "\t\t" + movie.getNumber() + "\t\t"
    251. + sdf.format(movie.getStartTime()) ); // 格式化,上映时间
    252. }
    253. }else { // 小于0部,证明没有片子上映
    254. System.out.println("您的店铺当前无片放映");
    255. }
    256. }
    257. private static void showCustomerMain() {
    258. while (true) {
    259. System.out.println("============黑马电影客户界面===================");
    260. System.out.println(loginUser.getUserName() + (loginUser.getSex() == '男' ? "先生": "女生" + "欢迎来到该系统"));
    261. System.out.println("请您选择要操作的功能:");
    262. System.out.println("1、展示全部影片信息功能:");
    263. System.out.println("2、根据电影名称查询电影信息:");
    264. System.out.println("3、评分功能:");
    265. System.out.println("4、购票功能:");
    266. System.out.println("5、退出系统:");
    267. System.out.println("请输入您要操作的命令:");
    268. String command = SYS_SC.nextLine();
    269. switch (command){
    270. case "1":
    271. // 展示全部排片信息
    272. break;
    273. case "2":
    274. break;
    275. case "3":
    276. // 评分功能
    277. break;
    278. case "4":
    279. // 购票功能
    280. break;
    281. case "5":
    282. return; // 干掉方法
    283. default:
    284. System.out.println("不存在该命令!!");
    285. break;
    286. }
    287. }
    288. }
    289. // 定义一个搜索用户名的方法 getUserByLoginName
    290. public static User getUserByLoginName (String loginName) {
    291. // 遍历用户集合的每个元素ALL_USERS
    292. for (User user : ALL_USERS) { // 遍历出来的都是存储在User类的对象
    293. // 判断这个用户的登录名称是否是我们想要的
    294. if (user.getLoginName().equals(loginName)){
    295. // 判断用户的登录名是否和搜索的登录名是否一样
    296. return user; // 如果一样,返回该用户对象,代表查到了
    297. }
    298. }
    299. return null; // 否则就没查到,结束方法
    300. }
    301. }