项目学习巩固目标:
模拟实现一个基于文本界面的《拼电商客户管理系统》
进一步掌握编程技巧和调试技巧,熟悉面向对象编程
主要涉及以下知识点:
类结构的使用:属性、方法及构造器
对象的创建与使用
类的封装性
声明和使用数组
数组的插入、删除和替换
关键字的使用:this
模拟实现基于文本界面的《拼电商客户管理系统》。
该软件能够实现对客户对象的插入、修改和删除(用数组实现),并能够打印客户明细表。
项目采用分级菜单方式。主菜单如下:
-----------------拼电商客户管理系统-----------------
1 添 加 客 户
2 修 改 客 户
3 删 除 客 户
4 客 户 列 表
5 退 出
请选择(1-5):_
•每个客户的信息被保存在Customer对象中。
•以一个Customer类型的数组来记录当前所有的客户。
•每次“添加客户”(菜单1)后,客户(Customer)对象被添加到数组中。
•每次“修改客户”(菜单2)后,修改后的客户(Customer)对象替换数组中原对象。
•每次“删除客户”(菜单3)后,客户(Customer)对象被从数组中清除。
•执行“客户列表 ”(菜单4)时,将列出数组中所有客户的信息。
“添加客户”的界面及操作过程如下所示:
……
请选择(1-5):1
---------------------添加客户---------------------
姓名:佟刚
性别:男
年龄:35
电话:010-56253825
邮箱:[email protected]
---------------------添加完成---------------------
“修改客户”的界面及操作过程如下所示:
……
请选择(1-5):2
---------------------修改客户---------------------
请选择待修改客户编号(-1退出):1
姓名(佟刚):<直接回车表示不修改>
性别(男):
年龄(35):
电话(010-56253825):
邮箱([email protected]):[email protected]
---------------------修改完成---------------------
“删除客户”的界面及操作过程如下所示:
……
请选择(1-5):3
---------------------删除客户---------------------
请选择待删除客户编号(-1退出):1
确认是否删除(Y/N):y
---------------------删除完成---------------------
“客户列表”的界面及操作过程如下所示:
……
请选择(1-5):4
---------------------------客户列表---------------------------
编号 姓名 性别 年龄 电话 邮箱
1 佟刚 男 45 010-56253825 [email protected]
2 封捷 女 36 010-56253825 [email protected]
3 雷丰阳 男 32 010-56253825 [email protected]
-------------------------客户列表完成-------------------------
Ø CustomerView(视图)为主模块,负责菜单的显示和处理用户操作
Ø CustomerList为Customer对象的管理模块,内部用数组管理一组Customer对象,并提供相应的添加、修改、删除和遍历方法,供CustomerView调用(操作数组的行为都放在CustomerList里面)
Ø Customer为实体对象,用来封装客户信息(数组是Customer类类型的,也可以设计为JavaBean)
Customer为实体类,用来封装客户信息
String name
:客户姓名char gender
:性别int age
:年龄String phone
:电话号码String email
:电子邮箱代码
【Customer.java】
package yuyi03;
/**
* ClassName: Customer
* Package: yuyi03
* Description:
* 客户类
* @Author 雨翼轻尘
* @Create 2023/10/28 0028 18:30
*/
public class Customer {
//属性
private String name; //客户姓名
private char gender; //性别
private int age; //年龄
private String phone; //电话号码
private String email; //电子邮箱
//方法
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 String getName(){
return name;
}
public String getDetails(){
return name + "\t" +gender +"\t" +age+ "\t" +phone +"\t"+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;
}
}
CustomerList为Customer对象的管理模块,内部使用数组管理一组Customer对象
Customer[] customers
:用来保存客户对象的数组int total = 0
:记录已保存客户对象的数量⚡各方法的作用与参数:
①public CustomerList(inttotalCustomer)
②public booleanaddCustomer(Customer customer)
③public booleanreplaceCustomer(int index, Customer cust)
用途:用参数customer替换数组中由index指定的对象
参数:customer指定替换的新客户对象
index指定所替换对象在数组中的位置,从0开始
返回:替换成功返回true;false表示索引无效,无法替换
/**
* 用途:从数组中删除参数index指定索引位置的客户对象记录
* @param index 参数: index指定所删除对象在数组中的索引位置,从0开始
* @return 返回:删除成功返回true;false表示索引无效,无法删除
*/
public boolean deleteCustomer(int index){
//后边元素往前挪
if(index>=0 && index<total){
for (int i = index; i <total-1 ; i++) { //比如现在有3个元素,角标是0-2,index为1(第二个元素),角标为2的元素(第三个)往前移动,现在只有两个元素,角标不能超过1
customers[i]=customers[i+1]; //i的最大值是tatal-2,则customers[i+1]最大值为customers[total-1]
}
//将有效数据最后一个位置置空
customers[total-1]=null;
total--; //总人数减一
return true;
}else{
return false;
}
}
还可以这样:
/**
* 用途:从数组中删除参数index指定索引位置的客户对象记录
* @param index 参数: index指定所删除对象在数组中的索引位置,从0开始
* @return 返回:删除成功返回true;false表示索引无效,无法删除
*/
public boolean deleteCustomer(int index){
if(index<0 || index>=total){
return false;
}
for (int i = index; i < total-1; i++) {
customers[i]=customers[i+1];
}
//将有效数据最后一个位置置空
//customers[total-1]=null;
//total--;
//或
customers[--total]=null;
return true;
}
④public booleandeleteCustomer(int index)
⑤public Customer[] getAllCustomers()
⑥public Customer getCustomer(int index)
代码
【CustomerList.java】
package yuyi03;
/**
* ClassName: CustomerList
* Package: yuyi03
* Description:
* CustomerList为Customer对象的管理模块,内部使用数组管理一组Customer对象
* @Author 雨翼轻尘
* @Create 2023/10/28 0028 18:47
*/
public class CustomerList {
//属性
private Customer[] customers; //用来保存客户对象的数组
private int total; //记录已保存客户对象的数量
//构造器
/**
* 用途:构造器,用来初始化customers数组
* @param totalCustomer 指定customers数组的最大空间
*/
public CustomerList(int totalCustomer){
customers=new Customer[totalCustomer];
}
//方法
/**
* 用途:将参数customer添加组中最后一个客户对象记录之后
* @param customer 参数:customer指定要添加的客户对象
* @return 返回:添加成功返回true;false表示数组已满,无法添加
*/
public boolean addCustomer(Customer customer){
if(total<customers.length){ //若此时客户对象的数量(total)小于数组长度,说明数组没有满,可以添加客户进去
customers[total]=customer;
total++; //加完一个客户进数组,客户对象数量加一
return true;
}else{
return false;
}
}
/**
* 用途:用参数cust替换数组中由index指定的对象
* @param index index指定所替换对象在数组中的位置,从0开始
* @param cust 参数:cust 指定替换的新客户对象
* @return 返回:替换成功返回true;false表示索引无效,无法替换
*/
public boolean replaceCustomer(int index, Customer cust){
if(index>=0 && index<total){
customers[index]=cust;
return true;
}else{
return false;
}
}
/**
* 用途:从数组中删除参数index指定索引位置的客户对象记录
* @param index 参数: index指定所删除对象在数组中的索引位置,从0开始
* @return 返回:删除成功返回true;false表示索引无效,无法删除
*/
public boolean deleteCustomer(int index){
if(index<0 || index>=total){
return false;
}
for (int i = index; i < total-1; i++) {
customers[i]=customers[i+1];
}
//将有效数据最后一个位置置空
//customers[total-1]=null;
//total--;
//或
customers[--total]=null;
return true;
}
/**
* 用途:返回数组中记录的所有客户对象
* @return 返回: Customer[] 数组中包含了当前所有客户对象,该数组长度与对象个数相同。
*/
public Customer[] getAllCustomers(){
//错误的:
//return customers; 会将空的元素也一起返回,现在只需要有客户的对象元素
//正确的:
Customer[] cus=new Customer[total]; //要是一个也没有存,total是0,循环进不去,直接返回,相当于造了一个长度为0的数组
for (int i = 0; i < total; i++) { //total也可以改为cus.length
cus[i]=customers[i]; //没有将对象复制过来,只是将地址复制过来了,对象还是原来的那个
}
return cus;
}
/**
* 用途:返回参数index指定索引位置的客户对象记录
* @param index 参数: index指定所要获取的客户在数组中的索引位置,从0开始
* @return 返回:封装了客户信息的Customer对象
*/
public Customer getCustomer(int index){
if(index>0 || index<total){ //index有效范围
return customers[index];
}else{
return null;
}
}
/**
*获取客户列表中客户的数量
* @return 客户数量total
*/
public int getTotal(){
return total;
}
}
CustomerView为主模块,负责菜单的显示和处理用户操作
⚡各方法的作用与参数:
①public void enterMainMenu()
②private void addNewCustomer()
private void modifyCustomer()
private void deleteCustomer()
private void listAllCustomers()
③public static void main(String[] args)
代码
【CustomerView.java】
package yuyi03;
/**
* ClassName: CustomerView
* Package: yuyi03
* Description:
* CustomerView为主模块,负责菜单的显示和处理用户操作
* @Author 雨翼轻尘
* @Create 2023/10/29 0029 10:16
*/
public class CustomerView {
//造CustoomerList的对象,作为当前类的属性出现
CustomerList customerList = new CustomerList(10); //数组长度为10,最多添加10个客户
//方法
/**
* 进入主界面的方法
*/
public void enterMainMenu(){
boolean isFlag=true;
while(isFlag){
//显示界面
System.out
.println("\n-------------------拼电商客户管理系统-----------------\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 key = CMUtility.readMenuSelection(); //让用户从1-5做选择,不是这个范围就出不来
switch(key){
case '1':
//添加客户
addNewCustomer();
break;
case '2':
//修改客户
modifyCustomer();
break;
case '3':
//删除客户
deleteCustomer();
break;
case'4':
//客户列表
listAllCustomers();
break;
case '5':
System.out.print("确认是否退出(Y/N):");
char isExit=CMUtility.readConfirmSelection();
if(isExit=='Y'){ //Y要大写,因为在CMUtility.readConfirmSelection()方法里面给它转成大写的了
//获取用户选择为5的时候退出
isFlag=false;
}
//若是N就不用管它了,继续循环即可
break;
}
}
}
//添加客户
private void addNewCustomer(){
System.out.println("---------------------添加客户---------------------");
System.out.print("姓名:");
String name = CMUtility.readString(4);
System.out.print("性别:");
char gender = CMUtility.readChar();
System.out.print("年龄:");
int age = CMUtility.readInt();
System.out.print("电话:");
String phone = CMUtility.readString(15);
System.out.print("邮箱:");
String email = CMUtility.readString(15);
Customer cust = new Customer(name, gender, age, phone, email);
boolean flag = customerList.addCustomer(cust);
if (flag) {
System.out
.println("---------------------添加完成---------------------");
} else {
System.out.println("----------------记录已满,无法添加-----------------");
}
}
private void modifyCustomer() {
System.out.println("---------------------修改客户---------------------");
int index = 0;
Customer cust = null;
for (;;) {
System.out.print("请选择待修改客户编号(-1退出):");
index = CMUtility.readInt();
if (index == -1) {
return;
}
cust = customerList.getCustomer(index - 1);
if (cust == null) {
System.out.println("无法找到指定客户!");
} else
break;
}
System.out.print("姓名(" + cust.getName() + "):");
String name = CMUtility.readString(4, cust.getName());
System.out.print("性别(" + cust.getGender() + "):");
char gender = CMUtility.readChar(cust.getGender());
System.out.print("年龄(" + cust.getAge() + "):");
int age = CMUtility.readInt(cust.getAge());
System.out.print("电话(" + cust.getPhone() + "):");
String phone = CMUtility.readString(15, cust.getPhone());
System.out.print("邮箱(" + cust.getEmail() + "):");
String email = CMUtility.readString(15, cust.getEmail());
cust = new Customer(name, gender, age, phone, email);
boolean flag = customerList.replaceCustomer(index - 1, cust);
if (flag) {
System.out
.println("---------------------修改完成---------------------");
} else {
System.out.println("----------无法找到指定客户,修改失败--------------");
}
}
//删除客户
private void deleteCustomer() {
System.out.println("---------------------删除客户---------------------");
int index = 0;
Customer cust = null;
for (;;) {
System.out.print("请选择待删除客户编号(-1退出):");
index = CMUtility.readInt();
if (index == -1) {
return;
}
cust = customerList.getCustomer(index - 1);
if (cust == null) {
System.out.println("无法找到指定客户!");
} else
break;
}
System.out.print("确认是否删除(Y/N):");
char yn = CMUtility.readConfirmSelection();
if (yn == 'N')
return;
boolean flag = customerList.deleteCustomer(index - 1);
if (flag) {
System.out
.println("---------------------删除完成---------------------");
} else {
System.out.println("----------无法找到指定客户,删除失败--------------");
}
}
//客户列表
private void listAllCustomers() {
System.out.println("---------------------------客户列表---------------------------");
Customer[] custs = customerList.getAllCustomers();
if (custs.length == 0) {
System.out.println("没有客户记录!");
} else {
System.out.println("编号\t姓名\t\t性别\t年龄\t电话\t\t\t邮箱");
for (int i = 0; i < custs.length; i++) {
// System.out.println(i + 1 + "\t" + custs[i].getName() + "\t" + custs[i].getGender() + "\t" + custs[i].getAge() + "\t\t" + custs[i].getPhone() + "\t" + custs[i].getEmail());
System.out.println((i+1) + "\t" + custs[i].getDetails());
}
}
System.out.println("-------------------------客户列表完成-------------------------");
}
public static void main(String[] args){
//创建当前类的对象
CustomerView view =new CustomerView();
view.enterMainMenu();
}
}
项目中提供了CMUtility.java类,可用来方便地实现键盘访问。
该类提供了以下静态方法:
public static char readMenuSelection()
public static char readChar()和 public static char readChar(char defaultValue)
public static int readInt() 和public static int readInt(int defaultValue)
public static String readString(int limit) 和public static String readString(int limit, String defaultValue)
用途:这两个方法功能相同,均从键盘读取一个长度不超过limit的字符串,并将其作为方法的返回值。
参数:limit — 指定字符串的最大长度
defaultValue— 如果用户不输入字符而直接回车,方法将以defaultValue 作为返回值。
public static char readConfirmSelection()
【CMUtility.java】
package com.atguigu02.project;
import java.util.Scanner;
/**
* CMUtility工具类:
* 将不同的功能封装为方法,就是可以直接通过调用方法使用它的功能,而无需考虑具体的功能实现细节。
*
* @author 尚硅谷-宋红康
* @create 17:17
*/
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.print("数字输入错误,请重新输入:");
}
}
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.print("数字输入错误,请重新输入:");
}
}
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() {
char c;
for (; ; ) {
String str = readKeyBoard(1, false).toUpperCase();
c = str.charAt(0);
if (c == 'Y' || c == 'N') {
break;
} else {
System.out.print("选择错误,请重新输入:");
}
}
return c;
}
private static String readKeyBoard(int limit, boolean blankReturn) {
String line = "";
while (scanner.hasNextLine()) {
line = scanner.nextLine();
if (line.length() == 0) {
if (blankReturn) return line;
else continue;
}
if (line.length() < 1 || line.length() > limit) {
System.out.print("输入长度(不大于" + limit + ")错误,请重新输入:");
continue;
}
break;
}
return line;
}
}