java面向对象程序设计
题目:
设计思路:
1.该题目从题干来看较为简单,需求较少,因此第一步,我们便要搞懂该程序的功能需求:该程序模拟全球通计费系统,需要我们给电话号码计算花费并可以查询显示当月实时账单。那么,我们可以从增删改查出发,一个特定号码我们可以理解为一个电话用户,即我们可以添加一个电话用户,之后对这位用户的通话进行记录,记录的同时计算该用户的消费金额,当我们查询时,将该金额进行显示出来;
2.搞清楚需求之后,我们下一步做的事准备工作,首先就是资料查询,即关于全球通计费的资料查询,该题目要求我们使用真实的全球通资费标准,那么我就要知道该标准,并用我们的程序将其统一的表示起来。
全球通计费标准(仅供参考)(该程序中只使用前两个套餐,原理都一样)
3.对题目分析完成之后,我们便要开始程序的简单构架,首先我们需要一个用户类,用来记录用户的电话和消费记录,从上述信息可以看出,消费主要通过月租、来电显示、市话、国内漫游、长途、国际长途,我们可以将这些作为该类的属性进行记录,同时用sumPrice用来记录总消费;在我们明白如何对数据进行记录之后,下一步要做的便是如何操作这些数据来达到我们的功能需求:在这里为了增加可读性,我使用了一个接口对我们需要的操作进行一个简单的陈列,之后在行为类中国对这些方法进行实现就可以了;最终的结果是在主类里面显示出来。
知识储备:
该程序难度较低,可以作为刚入门的人员或者大一新生对自己的阶段性检测,涉及到的知识点如下:
1.异常处理机制:这个是为了增加程序的健壮性,避免程序在失误输入下崩溃;
2.链表的使用:这个是为了存储数据,使用链表存储数据较数组相比更为方便和修改;
3.正则表达:这个是为了对电话号码的输入进行筛选,希望输入的电话号码符合实际情况;
4.面向对象思想:这个是该程序的核心思想,该思想对于刚开始接触编程的人来说可能有点抽象,你们可以参考我的上一篇课设文章(学生学籍管理系统),会发现这个程序代码更加简洁,其简洁主要体现在方法的调用上面(当然,这里的功能也较少),在这个代码里面,我更多的是去调用方法,而不是重复写代码,举个例子:这种程序都涉及到大量的输入输出,那么对于输入的格式就必须有一个要求,即在这里用的异常处理机制,我在上一篇课设文章也使用到了异常处理,不过当时并没有通过调用方法来实现,而是在每次输入的时候都进行异常判断,这便使得代码量剧增。而在这个程序中,我写了一个异常处理方法,用来对输入的数据进行判断,如果数据符合要求,则对其赋值,不符合要求,则将数值设置为0,便可以实现我们的需求。这个便是面向对象思想的一个简单使用,可以多看几遍这块代码,去做一下对比,体会一下面向对象的含义。
注:在该程序中,大量使用私有方法,可以多观察这些方法的调用,想一下为什么要这样写,可能会增加你们对面向对象的理解(PS:该程序中对执行的格式要求有所降低,你们可以根据自己的风格调整格式)
代码:
//用户(电话)类:
/**
* @ClassName 电话类
* @Description TODO
* @Author 今夕河西
* @Date 2022-09-09 14:46
* @Version 1.0
**/
public class Phone {
private String phone_number; //电话号码
private double yz; //月租
private double ldxs; //来点显示
private double time_sh; //市话时间
private double time_gnmy; //国内漫游
private double time_ct; //长途
private double sum_price; //整体收费
public String getPhone_number() {
return phone_number;
}
public void setPhone_number(String phone_number) {
this.phone_number = phone_number;
}
public double getYz() {
return yz;
}
public void setYz(double yz) {
this.yz = yz;
}
public double getLdxs() {
return ldxs;
}
public void setLdxs(double ldxs) {
this.ldxs = ldxs;
}
public double getTime_sh() {
return time_sh;
}
public void setTime_sh(double time_sh) {
this.time_sh = time_sh;
}
public double getTime_gnmy() {
return time_gnmy;
}
public void setTime_gnmy(double time_gnmy) {
this.time_gnmy = time_gnmy;
}
public double getTime_ct() {
return time_ct;
}
public void setTime_ct(double time_ct) {
this.time_ct = time_ct;
}
public double getSum_price() {
return sum_price;
}
public void setSum_price(double sum_price) {
this.sum_price = sum_price;
}
public Phone(String phone_number, double yz, double ldxs, double time_sh, double time_gnmy, double time_ct) {
this.phone_number = phone_number;
this.yz = yz;
this.ldxs = ldxs;
this.time_sh = time_sh;
this.time_gnmy = time_gnmy;
this.time_ct = time_ct;
}
public Phone() {
}
@Override
public String toString() {
return "Phone{" +
"电话号码='" + phone_number + '\'' +
", 月租金额=" + yz +
", 来电显示金额=" + ldxs +
", 市话通话时长=" + time_sh +
", 国内漫游通话时长=" + time_gnmy +
", 长途通话时长=" + time_ct +
", 总计消费金额=" + sum_price +
'}';
}
}
//行为接口:
/**
* @InterfaceName 接口--行为展示
* @Description TODO
* @Author 今夕河西
* @Date 2022-09-09 14:47
* @Version 1.0
**/
public interface ActionImplement {
//创建用户
void addPhone();
//拨打电话
void add_call();
//查询本月消费
void select_price();
}
//行为实现
import java.util.LinkedList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @ClassName 行为方法类
* @Description TODO
* @Author 今夕河西
* @Date 2022-09-09 14:47
* @Version 1.0
**/
public class Action implements ActionImplement{
//创建两个链表来接收两种套餐
public LinkedList<Phone> linkedList1 = new LinkedList<Phone>(); //第一种套餐
public LinkedList<Phone> linkedList2 = new LinkedList<Phone>(); //第二种套餐
@Override
public void addPhone() { //办理一个电话号码
Phone phone = new Phone();
Scanner scanner = new Scanner(System.in);
System.out.println("该功能为添加电话用户!");
System.out.print("请您输入电话号码:");
String phone_number = scanner.next();
while (!IsMobilphone(phone_number)) {
System.out.print("电话号码格式不正确,请重新输入:");
phone_number = scanner.next();
}
while (!IsExitPhone(phone_number)) {
System.out.print("该电话号码已存在,请重新输入:");
phone_number = scanner.next();
}
phone.setPhone_number(phone_number);
System.out.println("用户创建成功!");
view();
System.out.print("请为该用户选择套餐(选择套餐一请输入1,选择套餐二请输入2):");
int select_fa = scanner.nextInt();
while (select_fa != 1 && select_fa != 2) {
System.out.print("暂无其他套餐,请重新输入:");
select_fa = scanner.nextInt();
}
if (select_fa == 1) {
phone.setYz(50);
System.out.print("请选择是否需要来电显示(如果需要请输入1,不需要输入其他):");
int ldxh_select = scanner.nextInt();
if (ldxh_select == 1) {
phone.setLdxs(10);
} else {
phone.setLdxs(0);
}
linkedList1.add(phone); //套餐一在第一个链表里面
} else {
phone.setYz(25);
System.out.print("请选择是否需要来电显示(如果需要请输入1,不需要输入其他):");
int ldxh_select = scanner.nextInt();
if (ldxh_select == 1) {
phone.setLdxs(10);
} else {
phone.setLdxs(0);
}
linkedList2.add(phone);
}
}
@Override
public void add_call() {
Scanner scanner = new Scanner(System.in);
System.out.println("该功能为记录该月通话记录:");
System.out.println("请选择您要记录的手机号:");
String phone_number = scanner.next();
for (int i = 0; i < linkedList1.size(); i++) {
Phone phone = linkedList1.get(i);
if (phone.getPhone_number().equals(phone_number)) {
double time_sh = 0; //市话时间
double time_gnmy = 0; //国内漫游
double time_ct = 0; //长途
System.out.println("该用户为:" + phone_number);
System.out.print("请输入其市话通话时长(分钟):");
time_sh = IsExptaion(time_sh);
System.out.print("请输入其国内漫游通话时长:");
time_gnmy = IsExptaion(time_gnmy);
System.out.print("请输入其长途通话时长:");
time_ct = IsExptaion(time_ct);
phone.setTime_sh(time_sh);
phone.setTime_gnmy(time_gnmy);
phone.setTime_ct(time_ct);
} else {
if (i == linkedList1.size()) {
for (int j = 0; j < linkedList2.size(); j++) {
Phone phone1 = linkedList2.get(i);
if (phone1.getPhone_number().equals(phone_number)) {
double time_sh = 0; //市话时间
double time_gnmy = 0; //国内漫游
double time_ct = 0; //长途
System.out.println("该用户为:" + phone_number);
System.out.print("请输入其市话通话时长:");
time_sh = IsExptaion(time_sh);
System.out.print("请输入其国内漫游通话时长:");
time_gnmy = IsExptaion(time_gnmy);
System.out.print("请输入其长途通话时长:");
time_ct = IsExptaion(time_ct);
phone1.setTime_sh(time_sh);
phone1.setTime_gnmy(time_gnmy);
phone1.setTime_ct(time_ct);
} else {
if (j == linkedList2.size()) {
System.out.println("未查询到该用户,请检查是否输入正确!");
}
}
}
}
}
}
}
@Override
public void select_price() {
Scanner scanner = new Scanner(System.in);
System.out.println("该功能为查询该月账单记录:");
System.out.println("请选择您要记录的手机号:");
String phone_number = scanner.next();
for (int i = 0; i < linkedList1.size(); i++) {
Phone phone = linkedList1.get(i);
if (phone.getPhone_number().equals(phone_number)) {
phone.setSum_price(Computer_Price1(phone.getTime_sh(),phone.getTime_gnmy(),phone.getTime_ct()) + phone.getYz() + phone.getLdxs());
System.out.println(phone.toString());
} else {
if (i == linkedList1.size()) {
for (int j = 0; j < linkedList2.size(); j++) {
Phone phone1 = linkedList2.get(i);
if (phone1.getPhone_number().equals(phone_number)) {
phone1.setSum_price(Computer_Price2(phone1.getTime_sh(),phone1.getTime_gnmy(),phone1.getTime_ct()) + phone1.getYz() + phone1.getLdxs());
System.out.println(phone1.toString());
} else {
if (j == linkedList2.size()) {
System.out.println("未查询到该用户,请检查是否输入正确!");
}
}
}
}
}
}
}
//展示套餐信息
private void view () {
System.out.println("欢迎使用全球通:以下两种套餐供您选择:");
System.out.println("套餐一:计划套餐:");
System.out.println("月租50元,来电显示10元/月,市话0.4元/分,国内漫游费0.6元/分,长途费0.07元/6秒");
System.out.println("套餐二:自由套餐:");
System.out.println("月租25元,来电显示10元/月,市话0.2元/分,国内漫游费0.6元/分,长途费0.07元/6秒");
}
//判断手机号是否符合规定
private boolean IsMobilphone(String num) {
String regex1="0\\d{2,3}[-]?\\d{7,8}|0\\d{2,3}\\s?\\d{7,8}";
String regex2="1[3-9][0-9]\\d{8}";
//定义Pattern对象
Pattern pattern1=Pattern.compile(regex1);
Pattern pattern2=Pattern.compile(regex2);
//匹配对象
Matcher matcher1=pattern1.matcher(num);
Matcher matcher2=pattern2.matcher(num);
//bool函数判断输入是否正确
boolean boo1=matcher1.matches();
boolean boo2=matcher2.matches();
if (boo1) {
return true;
} else if (boo2) {
return true;
} else {
return false;
}
}
private double IsExptaion (double time) {
Scanner scanner = new Scanner(System.in);
try {
time = scanner.nextDouble();
} catch (Exception e) {
System.out.println("数据输入错误,该时间按照零来计算!");
return 0;
}
return time;
}
private boolean IsExitPhone (String phone_number) {
for (int i = 0; i < linkedList1.size(); i++) {
Phone phone = linkedList1.get(i);
if (phone.getPhone_number().equals(phone_number)) {
return false;
}
}
for (int i = 0; i < linkedList2.size(); i++) {
Phone phone = linkedList2.get(i);
if (phone.getPhone_number().equals(phone_number)) {
return false;
}
}
return true;
}
private double Computer_Price1 (double time1, double time2, double time3) {
double sum_price = time1 * 0.4 + time2 *0.6 + time3 * 0.07;
return sum_price;
}
private double Computer_Price2 (double time1, double time2, double time3) {
double sum_price = time1 * 0.2 + time2 *0.6 + time3 * 0.07;
return sum_price;
}
}
//主类展示
import java.util.Scanner;
/**
* @ClassName 主类
* @Description TODO
* @Author 今夕河西
* @Date 2022-09-09 14:44
* @Version 1.0
**/
public class Main {
public static void main(String[] args) {
System.out.println("欢迎使用全球通计费系统!");
run();
}
private static void showMenu () {
System.out.println("该系统功能如下所示:");
System.out.print("输入1:添加用户功能" + " ");
System.out.print("输入2:记录用户通话记录" + " ");
System.out.print("输入3:显示用户消费情况" + " ");
System.out.println("输入4:退出系统");
}
private static void run () {
Scanner scanner = new Scanner(System.in);
Action action = new Action();
System.out.println("请您先添加一名用户:");
action.addPhone();
boolean flag = true;
while (flag) {
showMenu();
System.out.print("请输入您要选择的功能");
int number = scanner.nextInt();
switch (number) {
case 1: {
System.out.println("欢迎使用功能1!");
action.addPhone();
System.out.println("该功能结束,即将跳出功能1!");
System.out.println("请继续选择功能!");
System.out.println();
break;
}
case 2: {
System.out.println("欢迎使用功能2!");
action.add_call();
System.out.println("该功能结束,即将跳出功能2!");
System.out.println("请继续选择功能!");
System.out.println();
break;
}
case 3: {
System.out.println("欢迎使用功能3!");
action.select_price();
System.out.println("该功能结束,即将跳出功能3!");
System.out.println("请继续选择功能!");
System.out.println();
break;
}
case 4: {
System.out.println("感谢您的使用!");
flag = false;
break;
}
default: {
System.out.println("该功能尚未开发,敬请期待!");
break;
}
}
}
}
}
运行结果: