这两天除了上课时间之外,一直在看一个“客户信息管理系统”,一套代码敲下来,收获颇丰,下面对这个小的项目(或者说是案例,)进行一个总结吧!

具体的解释以及思路,我写在了代码中间,以注释的形式来表现。

要实现的功能

编写一个客户信息管理系统,实现对于客户基本信息的“增、删、查、改”的操作。

虽然看起来功能都不算难,但是编程的过程中,着实不易。
主要将功能封装在4个类中:

CustomerView:

作为主模块,负责菜单的显示和处理用户操作

CustomerList

作为Customer对象的管理模块,内部用数组管理一组Customer对象,并提供相应的添加、修改、删除和遍历方法,
供CustomerViewer调用

Customer

作为实体对象,用来封装客户信息

CMUtility

CMUtility工具类,将不同的功能封装为方法,就是可以直接通过调用方法使用它的功能,而无需考虑具体的功能实现细节

具体的代码实现如下:(另外在文章本文的末尾附有完整的源代码压缩包,可供下载)

1、CustomerView类:

/** 作为主模块,负责菜单的显示和处理用户操作*/
/*** * @Description 主模块,负责菜单的显示和处理用户操作* @author admin**/
public class CustomerView {/** 实例化一个CustomerList类的对象, 要注意的是:在实例化创建CustomerList类的对象customerList的时候,* 会调用CustomerList类的构造函数,* 也就是我们自己写上去的那个有参(参数为totalcustomer,即:Customer[]数组长度的)构造函数*/private CustomerList customerList = new CustomerList(10);/** 便于测试------>提供一个当前类的构造器, 以便在创建对象的过程中就给对象数组就产生了一个信息*/// 构造器public CustomerView() {Customer customer = new Customer("王涛", '男', 23, "17513312345", "wt@163.com");/** 添加一个客户,将它放在数组当中*/customerList.addCustomer(customer);}/** 显示《客户信息管理软件》界面的方法*/private void enterMainMenu() {boolean isFlag = true;while (isFlag) {System.out.println("\n----------客户信息管理软件----------");System.out.println("            1、添加客户");System.out.println("            2、修改客户");System.out.println("            3、删除客户");System.out.println("            4、客户列表");System.out.println("            5、退出\n");System.out.print("            请选择(1-5):");char menu = CMUtility.readMenuSelection();/** 得到menu之后,到底是哪一个,需要一个分支语句*/switch (menu) {case '1':addNewCustomer();break;case '2':modifyCustomer();break;case '3':deleteCustomer();break;case '4':listAllCustomers();break;case '5':/** 因为没有写退出的方法,可以直接将退出的方法写到这里*/System.out.print("是否确认退出(Y/N):");/** 调用CMUtility.readConfirmSelection() 将输入的字符串(包容误输入)取第一个值,并且转换为对应的大写字母*/char isExit = CMUtility.readConfirmSelection();if (isExit == 'Y') {isFlag = false;}/** 如果输入的是N,结束case,就直接回到循环,执行下一次循环了*/}}}/** 添加客户的操作*/private void addNewCustomer() {System.out.println("---------------------------添加客户-----------------------------");System.out.print("姓名:");/** 读入姓名*/String name = CMUtility.readString(10);System.out.print("性别:");char gender = CMUtility.readChar();System.out.print("年龄:");int age = CMUtility.readInt();System.out.print("电话:");String phone = CMUtility.readString(13);System.out.print("邮箱:");String email = CMUtility.readString(30);/** 将上述数据封装到一个对象中,再将这个对象放入customerList[]数组中去*/Customer customer = new Customer(name, gender, age, phone, email);/** 不一定可以添加成功*/boolean isSuccess = customerList.addCustomer(customer);if (isSuccess) {System.out.println("---------------------------添加完成-----------------------------");} else {System.out.println("-----------------------客户目录已满,添加失败--------------------------");}}/** 修改客户的操作*/private void modifyCustomer() {//      System.out.println("修改客户的操作");System.out.println("---------------------------修改客户-----------------------------");/** 声明一个Customer对象:存储查找到的要修改信息的元素的内容 (是一个地址值或者是一个null) 因为是引用数据类型*/int number;Customer cust;/** 不知道循环要执行多少次 具体的循环次数,依据输入的信息而定,如果输入的一直不合法 就一直在这个循环内,提醒用户输入*/for (;;) {/** 这个循环只有两个出口: 1、输入的number==-1,退出修改的功能 2、break,进入到修改信息的具体功能实现的模块*/System.out.println("请选择待修改的客户编号(-1退出)");number = CMUtility.readInt();// 记录要修改的编号if (number == -1) {return;// 此时结束此方法,直接回到switch-case中的相应位置}/** 如果不是-1,也要输入的合理才可以 调用customerList.getCustomer方法 ------>* 如果合理,就返回对象数组中对应的元素的值(是该元素所存储的对象地址) 如果不合理,根据该函数可知,返回的是null ----------* 需要注意的是,用户输入的number比实际的索引值要 大1*/cust = customerList.getCustomer(number - 1);/** 判断cust是否靠谱*/if (cust == null) {System.out.println("无法找到指定的客户!");// 此时继续提示用户输入要自改的数据对应的编号----继续这个循环的下一轮} else {// 找到相应编号的客户break;// 将相应的操放到这个for循环的外边写}}/** 因为可以跑到这里的,就一定是通过break额 ---->输入的编号值合法的 所以,在这里编写修改相应信息的代码*/System.out.println("姓名(" + cust.getName() + "):");/** 如果用户没有直接换行,就以输入的姓名为准 如果用户直接换行,就以cust.getName()得到的值为准*/// 记录修改后,各个元素应该有的值String name = CMUtility.readString(10, cust.getName());System.out.println("性别(" + cust.getGender() + "):");char gender = CMUtility.readChar(cust.getGender());System.out.println("年龄(" + cust.getAge() + "):");int age = CMUtility.readInt(cust.getAge());System.out.println("电话(" + cust.getPhone() + "):");String phone = CMUtility.readString(13, cust.getPhone());System.out.println("邮箱(" + cust.getEmail() + "):");String email = CMUtility.readString(30, cust.getEmail());/** 将上述数据封装到一个对象中,再将这个对象放入customerList[]数组中去*/Customer newCust = new Customer(name, gender, age, phone, email);/** number-1 是对应的对象数组的索引值* * 做替换不一定能够换成,得再加上一个判断*/boolean isRepalaced = customerList.replaceCustomer(number - 1, newCust);if (isRepalaced) {System.out.println("---------------------------修改完成-----------------------------");}// 其实,现编的情况是没有可能会出现的else {System.out.println("---------------------------修改失败-----------------------------");}}/** 删除客户的操作*/private void deleteCustomer() {System.out.println("---------------------------删除客户-----------------------------");int number;/** 此循环只有两个出口:* 1、number==-1,直接接退出删除的功能* 2、最终的number满足删除的要求,实现了break,进入到剩下的部分* (此方法剩下的部分的内容是 :实现对于删除的具体操作* ----实际上也是调用方法来实现的* 调用的是CustomerList的deleteCustomer方法)*/for(;;) {//具有跟修改相似的循环逻辑System.out.println("请选择待删除的客户编号(-1退出)");number = CMUtility.readInt();//注意:number的有效范围是从1 开始到totalif(number == -1 ) {return;}//不是输入-1,确是是要修改信息/** 注意:number-1才是对应的索引值* 因为用户是从1开始算的* 而java中是从0开始计算的*/Customer customer = customerList.getCustomer(number - 1);/** 可能找不到指定的客户信息----customer不靠谱* 此时customer的值为null*/if(customer == null) {System.out.println("无法找到指定用户!");//此时将结束本次循环,进入下一轮的for循环中去} else {break;}}//找到了指定的客户,开始执行删除操作System.out.println("是否确认删除(Y/N)");char isDelete = CMUtility.readConfirmSelection();/** 判断是否输入Y或者y* 但是判断的时候只用判断是否为Y即可* 因为调用的CMUtility.readConfirmSelection(),实现了将输入的字符串中的首字符转换为大写的功能*/if(isDelete == 'Y') {boolean deleteSuccess = customerList.deleteCustomer(number-1);if(deleteSuccess ) {System.out.println("---------------------------删除成功-----------------------------");}
//          else {//              System.out.println("---------------------------删除失败-----------------------------");
//          }//实际上,没有机会执行}//如果输入的是n----直接退出这个方法,回到switch-case,继而回到主界面
//      else {//          return;//要不要这个无所谓。因为已经在方法的末尾了
//      }}/** 显示客户列表的操作*/private void listAllCustomers() {System.out.println("---------------------------客户列表-----------------------------");/** 先判断数组(是对象数组)中存放的有没有数据*/int total = customerList.getTotal();if (total == 0) {System.out.println("没有客户记录!");} else {/** 找到客户记录*/System.out.println("编号\t姓名\t性别\t年龄\t电话\t\t邮箱");/** 列出客户记录*/// 获取到数组中存储到的数据Customer[] custs = customerList.getAllCustomers();for (int i = 0; i < custs.length; i++) {/** 新造的数组中的每个元素,存储的都是对应的对象的存储地址 也就是一个对象元素*/Customer cust = custs[i];System.out.println(i + 1 + "\t" + cust.getName() + "\t" + cust.getGender() + "\t" + cust.getAge() + "\t"+ cust.getPhone() + "\t" + cust.getEmail());}}System.out.println("-------------------------客户列表完成----------------------------");}public static void main(String[] args) {/** 登陆进去要先显示主菜单 main()方法想要调用显示主菜单的方法 就应该先创建一个当前类的对象*/CustomerView view = new CustomerView();// 显示主菜单view.enterMainMenu();}}

2、CustomerList类

/** 作为Customer对象的管理模块,* 内部用数组管理一组Customer对象,* 并提供相应的添加、修改、删除和遍历方法,* 供CustomerViewer调用 */
/*** * @Description  作为Customer对象的管理模块,内部用数组管理一组Customer对象,* @author admin**/
public class CustomerList {//属性private Customer[] customers ;//用来保存客户对象的数组private int total = 0;//记录已保存客户对象的数量/** total的值是0 ,* 显示初始化为0,或者不写的话,默认的初始化值也是0*///提供以下构造器、方法/** 构造器* 初始化数组,* 参数totalcustomer表示数组有多长*/public CustomerList(int totalcustomer) {/** 当创建CustomerList对象的时候,就在这个构造函数中,将数组初始化* 操作数组之前一定要将其初始化*/customers = new Customer[totalcustomer];}/** 增----将指定的客户customer添加到数组中* 添加成功----返回true* 添加失败----返回false(满了就失败了)*/public boolean addCustomer(Customer customer) {/** 先判断是否满了----满了就添加不进去了*/if(total >= customers.length) {return false;//已经满了}/** 没有满的话,直接添加* ----添加的话,先放到数组的索引所指的位置,再将索引值 +1*/
//      customers[total] = customer;
//      total++;//或者customers[total++] = customer;return true;}/** 修改指定位置上的客户信息* ----形参是两个值,一个是要修改的下标索引;另一个是数组对应的元素要改的值*/public boolean replaceCustomer(int index,Customer cust) {/** index决定了是否可以修改*/if(index < 0 ||index >= total) {return false;}customers[index] = cust;/** 这里改的是指针* 原因在于:通过构造器创造出来的数组,其数组元素是Customer,* 而Customer又是一个对象,* ---->所以又new出来Customer对象,每个对象的地址值给了存储它的数组元素* -------->数组中的每个位置放置的是:一个Customer类型的对象的地址* -----------------* 现在做的replace操作,就是:* 又new出来一个对象,它的地址为cust* 现在需要将数组中索引值为index的元素中存储的值,改为cust* (使index的索引,指向地址cust存储的Customer对象)* 而原来的index处存储的那个地址所指向的Customer对象,因为没有指针指向,就被当做垃圾销毁*/return true;}/** 删除指定索引位置上的客户*/public boolean deleteCustomer(int index) {/** index决定了是否可以删除,跟修改一样,存在了才可以删除*/if(index < 0 ||index >= total) {return false;}/** 删掉的如果是位于中间位置的索引的话,不能直接将该索引对应的值置为null* 应将要删掉的索引的,后边的元素往前移,将现有的最后一个存储数据的索引值置为null* ------>这是因为数组是一段连续的空间,不允许中间空着,后边放别的*//** 写一个循环,将index小后边的元素一个个往前移* ---->需要注意的是:total记录的是元素的个数,* 即:比最后一个存储了元素的索引 大1* 但是需要注意的是,因为i表示的是将i+1的元素放到i上,所以i的最大值为total-2* 如果在这里不注意的话,容易产生下标越界的情况*/for(int i = index;i < total - 1;i++) {customers[i] = customers[i + 1];//数组元素前移}//最后有数据的元素需要置null
//      customers[total - 1] = null;
//      total--;//当前存储元素的索引最大值,也应该作出相应的变化//或者合并:customers[--total] = null;return true;}/** 查----获取所有的客户信息* 返回的是Customer[]类型的数组的首地址*/public Customer[] getAllCustomers() {/** 因为已有的数组中可能有空的元素* 所以不能直接返回已有的数组* ---->应该重新造一个元素来存储*/Customer[] custs = new Customer[total];//数组的复制for(int i = 0;i < custs.length;i++) {/** 并不是把每一个Customer对象都复制一份,复制的只是Customer[]数组中存储的地址值*/custs[i] = customers[i];}return custs;}/** 查----查循一个,具体查哪一个的话,按照索引判断* 获取指定位置上的客户* 返回值的类型是:Customer类的一个对象,* ----也即:Customer[]数值中的一个元素(虽然返回的是一个地址值,但是这个地址值指向的是一个Customer类的对象)* 又因为引用类型的默认初始化值为null,所以如果找不到的话,返回一个null即可*/public Customer getCustomer(int index) {/** index这个索引值,不一定靠谱,因为这个位置上不一定存储有元素*/if(index < 0 || index >= total) {return null;//找不到}return customers[index];       }/** 获取已经存储的客户的数量*/public int getTotal() {/** 因为total的值,代表的是所有的客户总数* 也是下一个将要存储的数组元素的索引值*/return total;}
}

3、Customer类

/** 作为实体对象,用来封装客户信息*/
/*** * @Description* @author admin**/
public class Customer {private String name;//客户姓名private char gender;//性别private int age;//年龄private String phone;//电话号码private String email;//电子邮箱//getxx、setxx方法public String getName() {return name;}public void setName(String name) {this.name = name;}public char getGender() {return gender;}public void setGender(char gender) {this.gender = gender;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public String getPhone() {return phone;}public void setPhone(String phone) {this.phone = phone;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}//提供构造器//先写一个空参的public Customer() {}//再写一个全参的public Customer(String name, char gender, int age, String phone, String email) {this.name = name;this.gender = gender;this.age = age;this.phone = phone;this.email = email;}
}
//实质上就是一个Javabean

4、CMUtility类

/*
* defaultValue* ----如果用户不输入字符而直接回车,方法将以defaultValue作为返回值* 在修改客户时调用*/
import java.util.*;
/** CMUtility工具类,* 将不同的功能封装为方法,* 就是可以直接通过调用方法使用它的功能,而无需考虑具体的功能实现细节*/
public class CMUtility {private static Scanner scanner = new Scanner(System.in);/** 用于界面菜单的选择* 该方法读取键盘:* 如果用户键入‘1’-‘5’中的任意字符,则方法返回。* 返回值为用户所选择的功能对应的字符*/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' && c != '5') {System.out.print("选择错误,请重新输入:");}else break;}return c;}/** 从键盘读取一个字符,并将其作为方法的返回值* 这里读取的是性别* ----* 与下边修改性别的方法构成重载*/public static char readChar() {String str = readKeyBoard(1,false);return str.charAt(0);}/** 从键盘读取一个字符,并将其作为方法的返回值* 如果用户不输入字符而直接回车,方法将以defaultValue 作为返回值* 修改性别的时候用到* ------* 如果用户没有输入的话,就拿形参的值再去填充,把它作为默认的值去返回*/public static char readChar(char defaultValue) {String str = readKeyBoard(1,true);return (str.length() == 0 )? defaultValue:str.charAt(0);}/** 从键盘读取一个长度不超过2位的整数* 读取的是年龄* */public static int readInt() {int n;for(;;) {String str = readKeyBoard(2,false);try {n = Integer.parseInt(str);break;} catch (NumberFormatException e) {System.out.println("数字输入错误,请重新输入:");}}return n;}/** 从键盘读取一个长度不超过2位的整数,并将其作为方法 的返回值* 如果用户不输入字符而直接回车,方法将以defaultValue 作为返回值* 在修改年龄的啥时候用到* */public static int readInt(int defaultValue) {int n;for(;;) {String str = readKeyBoard(2,true);if(str.equals("")) {return defaultValue;}try {n = Integer.parseInt(str);break;} catch (NumberFormatException e) {System.out.println("数字输入错误,请重新输入:");}}return n;}/** 从键盘读取一个长度不超过limit的字符串,并将其作为方法的返回值* 读取的是电话号码*/public static String readString(int limit) {return readKeyBoard(limit,false);}/** 从键盘读取一个长度不超过limit的字符串,将其作为方法的返回值* 如果用户不输入字符而直接回车,方法将以defaultValue 作为返回值* 修改的时候用到的方法* */public static String readString(int limit,String defaultValue) {String str = readKeyBoard(limit,true);return str.equals("")? defaultValue : str;}/** 用于确认选择的输入。该方法从键盘读取‘Y’或‘N',并将其作为方法的返回值* ----用于删除和退出的时候的  再次确认* */public static char readConfirmSelection() {/** 存储从键盘读入的字符串的第一个值(y 或者 n,或者错误的输入),* 并在确定输入的是y 或者 n,的情况下,返回对应的大写字母,以便进行比对*/char c;/** 循环的结束条件为空* 真正判断----结束循环的条件,在循环体中,* 何时结束循环,由输入的情况而定*/for(;;) {/** 将从键盘读取到的字符串,转换成大写再进行判断* 这样不论输入‘Y’还是‘y’,都可以使得正确退出*/String str = readKeyBoard(1,false).toUpperCase();/** 读取的是str中的第一个字符* 这样可以排除用户输入多余字符,而不能使程序正常结束的情况*/c = str.charAt(0);if(c == 'Y' || c == 'N') {break;} else {System.out.println("选择错误,请重新输入:");}}return c;}private static String readKeyBoard(int limit,boolean blankReturn) {String line = "";while(scanner.hasNextLine()) {/** 从键盘读取的字符串,赋值给line*/line = scanner.nextLine();if(line.length() == 0) {/** 如果line(从键盘读取到的字符串的长度为0----没有读入字符串)*/if(blankReturn) {return line;} else {continue;}}if(line.length() < 1 || line.length() > limit) {System.out.print("输入长度(不大于"+limit+")错误,请重新输入: ");continue;}break;}return line;}}

源代码可以在这里下载:

客户信息管理系统----Java实现(以对象数组为主)相关推荐

  1. 客户信息管理系统——Java

    客户信息管理系统--Java 该系统没有涉及文件及数据库,适合刚接触java的新手进行练习.模拟实现基于文本界面的客户软件管理系统.能够实现基本增删改查操作以及类的使用 文件排布如下图: 源代码 Cu ...

  2. 掌财社:Java项目案例之客户信息管理系统的实现

    本篇文章将使用所学过的Java知识来实现一个简单的客户信息管理系统的小项目,下面内容是具体地实现过程,这篇文章供大家参考学习,希望能帮助到大家. 类图: Customer类: public class ...

  3. Java项目二:客户信息管理系统(eclipse)

    文章目录 项目介绍 一.项目要求 1.添加客户 2.修改客户 3.删除客户 4.显示客户列表 二.软件设计结构 1.软件流程 2.CMUtility.java(实现键盘访问) 3.Customer.j ...

  4. java客户信息管理系统_JavaWeb客户信息管理系统.doc

    JavaWeb客户信息管理系统 xxxx 信息科学与工程学院 课程设计 题 目: 客户信息管理系统 姓 名: xxxx 学 号: xxxx 班 级: xxxx 课 程: Java Web 任课教师 x ...

  5. java计算机毕业设计房产客户信息管理系统源码+系统+lw文档+mysql数据库+部署

    java计算机毕业设计房产客户信息管理系统源码+系统+lw文档+mysql数据库+部署 java计算机毕业设计房产客户信息管理系统源码+系统+lw文档+mysql数据库+部署 本源码技术栈: 项目架构 ...

  6. java毕业生设计房产客户信息管理系统计算机源码+系统+mysql+调试部署+lw

    java毕业生设计房产客户信息管理系统计算机源码+系统+mysql+调试部署+lw java毕业生设计房产客户信息管理系统计算机源码+系统+mysql+调试部署+lw 本源码技术栈: 项目架构:B/S ...

  7. 【附源码】计算机毕业设计JAVA房产客户信息管理系统

    [附源码]计算机毕业设计JAVA房产客户信息管理系统[附源码] 目运行 环境项配置: Jdk1.8 + Tomcat8.5 + Mysql + HBuilderX(Webstorm也行)+ Eclis ...

  8. java毕业设计企业客户信息管理系统mybatis+源码+调试部署+系统+数据库+lw

    java毕业设计企业客户信息管理系统mybatis+源码+调试部署+系统+数据库+lw java毕业设计企业客户信息管理系统mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: 项目架构 ...

  9. 基于javaweb的crm客户关系管理系统(java+springboot+echarts+freemarker+layui+mysql)

    基于javaweb的crm客户关系管理系统(java+springboot+echarts+freemarker+layui+mysql) 运行环境 Java≥8.MySQL≥5.7 开发工具 ecl ...

  10. 常用API、String、StringBuilder、集合和客户信息管理系统

    API 概念:应用程序接口. javaAPI:指的是JDK中提供的各种功能的java类. String 概念: String类在java.long包下,使用时不需要导包! 特点: 字符串不可变,他们的 ...

最新文章

  1. 华东师范计算机入门平时作业,计算机入门模拟卷A-华东师范大学.doc
  2. 记录猫眼电影的自定义字体反爬
  3. 5m 云服务器2核4g_阿里云服务器2核4gb
  4. 【重磅发布】最风骚的走位,最撩人的峰会,裂变!变!变!变!变!变!抢!...
  5. 引流虚拟主机和服务器,建站使用云服务器和虚拟主机 哪个更好?
  6. atlas和ajaxpro以及微软企业级类库在一起得web配置文件
  7. 单例设计模式八种写法
  8. mysql -数据库(备份与恢复)
  9. 解压zip报错_Get新技能!利用Python自动解压各种压缩文件
  10. BTrace简介与使用说明
  11. c语言贪吃蛇(简易版本含完整代码)
  12. PPC软件测试自学,一个成功的PPC广告活动所需的五个步骤
  13. Linux挂在netapp存储,使用NFS4协议在NETAPP存储下不能MOUNT的分析和解决
  14. 【HUSTOJ】1053: 字符图形9-数字正三角
  15. 二维码与条形码的生成和识别使用
  16. 水源井远程监测控制系统 泵房无人值守方案
  17. 智能制造的实现,少不了APS排产系统
  18. 【R实验.7】回归分析
  19. java读取word文档的复杂表格_poi读取word表格 java POI 如何读取word的表格中的表格...
  20. MATLAB远程桌面不可启动——解决方法

热门文章

  1. php 数组json失败,php json转数组出错
  2. 激活函数(激励函数)理解总结
  3. Opencv安装与环境配置
  4. 安装opencv、测试opencv
  5. 简单通用的Makefile编写例子
  6. Javaweb实现在线预览word文件
  7. 【Vue项目实践】实现在线预览word文件、excel文件
  8. 基于android的校园二手交易平台的设计
  9. dnf电脑服务器不稳定怎么办,Win10玩DNF间歇性卡顿怎么办?Win10系统玩DNF卡顿解决方法(2)...
  10. 基于51单片机用按键和nrf24l01模块控制小车移动