一.前言:

本次Blog是对之前发布的PTA题目集的总结性Blog,这几次的作业题量,难度都不大,但都趋近于完成一整个系统,而非只实现部分的功能。题目集九、十也不在给出类图,而是要求自己设计。我认为这是比较好的,不想当码农,而是要自己的设计能力。这几次作业主要是迭代,从题目集八到十的电信计费系列从座机到手机再到短信,如果第一次没有设计好在后面会很不轻松。还有其他几道练习题,比较简单。

二.设计与分析、

实现一个简单的电信计费程序:
假设南昌市电信分公司针对市内座机用户采用的计费方式:
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
南昌市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。

输入格式:

输入信息包括两种类型
1、逐行输入南昌市用户开户的信息,每行一个用户,
格式:u-号码 计费类型 (计费类型包括:0-座机 1-手机实时计费 2-手机A套餐)
例如:u-079186300001 0
座机号码除区号外由是7-8位数字组成。
本题只考虑计费类型0-座机计费,电信系列2、3题会逐步增加计费类型。
2、逐行输入本月某些用户的通讯信息,通讯信息格式:
座机呼叫座机:t-主叫号码 接听号码 起始时间 结束时间
t-079186330022 058686330022 2022.1.3 10:00:25 2022.1.3 10:05:11
以上四项内容之间以一个英文空格分隔,
时间必须符合"yyyy.MM.dd HH:mm:ss"格式。提示:使用SimpleDateFormat类。
以上两类信息,先输入所有开户信息,再输入所有通讯信息,最后一行以“end”结束。
注意:
本题非法输入只做格式非法的判断,不做内容是否合理的判断(时间除外,否则无法计算),比如:
1、输入的所有通讯信息均认为是同一个月的通讯信息,不做日期是否在同一个月还是多个月的判定,直接将通讯费用累加,因此月租只计算一次。
2、记录中如果同一电话号码的多条通话记录时间出现重合,这种情况也不做判断,直接 计算每条记录的费用并累加。
3、用户区号不为南昌市的区号也作为正常用户处理。

输出格式:

根据输入的详细通讯信息,计算所有已开户的用户的当月费用(精确到小数点后2位,
单位元)。假设每个用户初始余额是100元。
每条通讯信息单独计费后累加,不是将所有时间累计后统一计费。
格式:号码+英文空格符+总的话费+英文空格符+余额
每个用户一行,用户之间按号码字符从小到大排序。

错误处理:
输入数据中出现的不符合格式要求的行一律忽略。

建议类图:
参见图1、2、3,可根据理解自行调整:

图1中User是用户类,包括属性:
userRecords (用户记录)、balance(余额)、chargeMode(计费方式)、number(号码)。 ChargeMode是计费方式的抽象类:
chargeRules是计费方式所包含的各种计费规则的集合,ChargeRule类的定义见图3。
getMonthlyRent()方法用于返回月租(monthlyRent)。 UserRecords是用户记录类,保存用户各种通话、短信的记录,
各种计费规则将使用其中的部分或者全部记录。
其属性从上到下依次是:
市内拨打电话、省内(不含市内)拨打电话、省外拨打电话、
市内接听电话、省内(不含市内)接听电话、省外接听电话的记录
以及发送短信、接收短信的记录。
 

图2中CommunicationRecord是抽象的通讯记录类:
包含callingNumber拨打号码、answerNumber接听号码两个属性。
CallRecord(通话记录)、MessageRecord(短信记录)是它的子类。 CallRecord(通话记录类)包含属性:
通话的起始、结束时间以及
拨号地点的区号(callingAddressAreaCode)、接听地点的区号(answerAddressAreaCode)。
区号用于记录在哪个地点拨打和接听的电话。座机无法移动,就是本机区号,如果是手机号,则会有差异。
 

图3是计费规则的相关类,这些类的核心方法是:
calCost(ArrayList<CallRecord> callRecords)。
该方法针根据输入参数callRecords中的所有记录计算某用户的某一项费用;如市话费。
输入参数callRecords的约束条件:必须是某一个用户的符合计费规则要求的所有记录。 LandPhoneInCityRule、LandPhoneInProvinceRule、LandPhoneInLandRule三个类分别是
座机拨打市内、省内、省外电话的计费规则类,用于实现这三种情况的费用计算。
(提示:可以从UserRecords类中获取各种类型的callRecords)。
 

后续扩展说明:
后续题目集将增加手机用户,手机用户的计费方式中除了与座机计费类似的主叫通话费之外,还包含市外接听电话的漫游费以及发短信的费用。在本题的设计时可统一考虑。
通话记录中,手机需要额外记录拨打/接听的地点的区号,比如:
座机打手机:t-主叫号码 接听号码 接听地点区号 起始时间 结束时间
t-079186330022 13305862264 020 2022.1.3 10:00:25 2022.1.3 10:05:11
手机互打:t-主叫号码 拨号地点 接听号码 接听地点区号 起始时间 结束时间
t-18907910010 0791 13305862264 0371 2022.1.3 10:00:25 2022.1.3 10:05:11
短信的格式:m-主叫号码,接收号码,短信内容
m-18907910010 13305862264 welcome to jiangxi
m-13305862264 18907910010 thank yo

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.Date;
public class Main {
public static void main(String[] args) throws ParseException{
SimpleDateFormat SimpleDateFormat=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
ArrayList<User> Users=new ArrayList<User>();
Scanner sc=new Scanner(System.in);
String a=sc.nextLine();
int m=0;
while(true)
{
if(a.matches("[u]-0791[0-9]{7,8} 0"))
{
Users.add(new User());
int q=a.indexOf(' ');
Users.get(m).number=a.substring(2,q);
Users.get(m).chargeMode=new LandlinePhoneCharging();
}
m++;
a=sc.nextLine();
if(a.charAt(0)=='t')
break;
}
String c=a;
while(!c.equals("end"))
{
int n=0;
int l=Users.size();
if(c.matches("t-[\\d]{11,12}\\s[\\d]{11,12}\\s[\\d]{4}.[\\d]{1,2}.[\\d]{1,2}\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])\\s[\\d]{4}.[\\d]{1,2}.[\\d]{1,2}\\s([0-1]?[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])"))
{
while(n<l)
{

try{
// 可能会导致错误的代码
int q=c.indexOf(' ');
if(Users.get(n).number.equals(c.substring(2,q)))
{

if(User.numaeral(c.substring(q+2,q+5))==0)
{

q=c.indexOf(' ',q+1);
int w=q;
q=c.indexOf(' ',q+1);
q=c.indexOf(' ',q+1);
if(check(c.substring(w+1, q))&&check(c.substring(q+1)))
{
Users.get(n).userRecords.callingInCityRecords.add(new CallRecord());
int le=Users.get(n).userRecords.callingInCityRecords.size();
Users.get(n).userRecords.callingInCityRecords.get(le-1).startTime=SimpleDateFormat.parse(c.substring(w+1, q));
Users.get(n).userRecords.callingInCityRecords.get(le-1).endTime=SimpleDateFormat.parse(c.substring(q+1));
}
}
else if(User.numaeral(c.substring(q+2,q+5))==1)
{

q=c.indexOf(' ',q+1);
int w=q;
q=c.indexOf(' ',q+1);
q=c.indexOf(' ',q+1);
if(check(c.substring(w+1, q))&&check(c.substring(q+1)))
{
Users.get(n).userRecords.callingInProvinceRecords.add(new CallRecord());
int le=Users.get(n).userRecords.callingInProvinceRecords.size();
Users.get(n).userRecords.callingInProvinceRecords.get(le-1).startTime=SimpleDateFormat.parse(c.substring(w+1, q));
Users.get(n).userRecords.callingInProvinceRecords.get(le-1).endTime=SimpleDateFormat.parse(c.substring(q+1));
}
}
else
{

q=c.indexOf(' ',q+1);
int w=q;
q=c.indexOf(' ',q+1);
q=c.indexOf(' ',q+1);
if(check(c.substring(w+1, q))&&check(c.substring(q+1)))
{
Users.get(n).userRecords.callingInLandRecords.add(new CallRecord());
int le=Users.get(n).userRecords.callingInLandRecords.size();
Users.get(n).userRecords.callingInLandRecords.get(le-1).startTime=SimpleDateFormat.parse(c.substring(w+1, q));
Users.get(n).userRecords.callingInLandRecords.get(le-1).endTime=SimpleDateFormat.parse(c.substring(q+1));
}
}
}
}
catch(Exception e){
// 在错误发生时怎么处理
}
n++;
}
}
c=sc.nextLine();
}
int y;
int j;
User t=new User();
for(y=0;y<Users.size();y++)
{
for(j=y+1;j<Users.size();j++)
{
if(Users.get(y).number.equals(Users.get(j).number))
{
Users.remove(j);
}
else if(Users.get(y).number.charAt(11)>Users.get(j).number.charAt(11))
{
t=Users.get(y);
Users.set(y, Users.get(j));
Users.set(j,t);
}

}
}
y=0;
while(y<Users.size())
{
System.out.printf("%s %.1f %.1f",Users.get(y).number,Users.get(y).calCost(),(80-Users.get(y).calCost()));
System.out.printf("\n");
y++;
}
}
static boolean check (String str) {
SimpleDateFormat sd=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");//括号内为日期格式,y代表年份,M代表年份中的月份(为避免与小时中的分钟数m冲突,此处用M),d代表月份中的天数
try {
sd.setLenient(false);//此处指定日期/时间解析是否不严格,在true是不严格,false时为严格
sd.parse(str);//从给定字符串的开始解析文本,以生成一个日期
}
catch (Exception e) {
return false;
}
return true;
}
}
abstract class CallChargeRule extends ChargeRule {
SimpleDateFormat SimpleDateFormat=new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");
public abstract double calCost (UserRecords userRecords);
}
class CallRecord extends CommunicationRecord{
Date startTime;
Date endTime;
String callingAddressAreaCode;
String answerAddressAreaCode;
public Date getStartTime() {
return startTime;
}
public void setStartTime(Date startTime) {
this.startTime = startTime;
}
public Date getEndTime() {
return endTime;
}
public void setEndTime(Date endTime) {
this.endTime = endTime;
}
public String getCallingAddressAreaCode() {
return callingAddressAreaCode;
}
public void setCallingAddressAreaCode(String callingAddressAreaCode) {
this.callingAddressAreaCode = callingAddressAreaCode;
}
public String getAnswerAddressAreaCode() {
return answerAddressAreaCode;
}
public void setAnswerAddressAreaCode(String answerAddressAreaCode) {
this.answerAddressAreaCode = answerAddressAreaCode;
}
}
abstract class chargeMode {
ArrayList<ChargeRule> chargeRules = new ArrayList<>();
public abstract double calCost (UserRecords userRecords);
public abstract double getMonthlyRent ();
public ArrayList<ChargeRule> getChargeRules() {
return chargeRules;
}
public void setChargeRules(ArrayList<ChargeRule> chargeRules) {
this.chargeRules = chargeRules;
}
}
abstract class ChargeRule {
public abstract double calCost (UserRecords userRecords);
}
abstract class CommunicationRecord {
String callingNumber;
String answerNumber;
public String getCallingNumber() {
return callingNumber;
}
public void setCallingNumber(String callingNumber) {
this.callingNumber = callingNumber;
}
public String getAnswerNumber() {
return answerNumber;
}
public void setAnswerNumber(String answerNumber) {
this.answerNumber = answerNumber;
}
}
class LandlinePhoneCharging extends chargeMode {

@Override
public double calCost(UserRecords userRecords) {
chargeRules.add(new LandPhoneInCityRule());
chargeRules.add(new LandPhoneInProvinceRule());
chargeRules.add(new LandPhoneInlandRule());
return chargeRules.get(0).calCost(userRecords)+chargeRules.get(1).calCost(userRecords)+chargeRules.get(2).calCost(userRecords);
}

@Override
public double getMonthlyRent() {
// TODO Auto-generated method stub
return 20;
}

}
class LandPhoneInCityRule extends CallChargeRule {
@Override
public double calCost(UserRecords userRecords) {
int i=0;
double s=0;
double m=0;
while(i<userRecords.callingInCityRecords.size())
{
try {
long time1=userRecords.callingInCityRecords.get(i).startTime.getTime();
long time2=userRecords.callingInCityRecords.get(i).endTime.getTime();
long time=(time2-time1);
i++;
s=(double)time;
m=Math.ceil(s/1000/60)*0.1+m;
}
catch(Exception e){
i++;
}
}
if(m>=0)
return m;
else
{
return 0;
}
}
}
class LandPhoneInlandRule extends CallChargeRule {

@Override
public double calCost(UserRecords userRecords) {
int i=0;
double s=0;
double m=0;
while(i<userRecords.callingInLandRecords.size())
{
try {
long time1=userRecords.callingInLandRecords.get(i).startTime.getTime();
long time2=userRecords.callingInLandRecords.get(i).endTime.getTime();
long time=(time2-time1);
i++;
s=(double)time;
m=m+Math.ceil(s/1000/60)*0.6;
}
catch(Exception e){
i++;
}
}
if(m>=0)
return m;
else
{
return 0;
}
}
}

class LandPhoneInProvinceRule extends CallChargeRule {

@Override
public double calCost(UserRecords userRecords) {
int i=0;
double s=0;
double m=0;
while(i<userRecords.callingInProvinceRecords.size())
{
try {
long time1=userRecords.callingInProvinceRecords.get(i).startTime.getTime();
long time2=userRecords.callingInProvinceRecords.get(i).endTime.getTime();
long time=(time2-time1);
i++;
s=(double)time;
m=Math.ceil(s/1000/60)*0.3+m;
}
catch(Exception e){
i++;
}
}
if(m>=0)
return m;
else
{
return 0;
}
}

}
class MessageRecord extends CommunicationRecord{
String message;

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}
}
class User {
UserRecords userRecords =new UserRecords();
double balance=100;
chargeMode chargeMode;
String number;
public UserRecords getUserRecords() {
return userRecords;
}
public void setUserRecords(UserRecords userRecords) {
this.userRecords = userRecords;
}
public double getBalance() {
return balance;
}
public chargeMode getChargeMode() {
return chargeMode;
}
public void setChargeMode(chargeMode chargeMode) {
this.chargeMode = chargeMode;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public double calBalance () {
return balance;
}
public double calCost () {
return chargeMode.calCost(userRecords);
}
public static int numaeral(String number) {
if(Integer.parseInt(number)==791)
return 0;
else if(Integer.parseInt(number)>=790&&Integer.parseInt(number)<799||Integer.parseInt(number)==701)
return 1;
else
return 2;
}
}
class UserRecords {
ArrayList<CallRecord> callingInCityRecords=new ArrayList<CallRecord>();
ArrayList<CallRecord> callingInProvinceRecords =new ArrayList<CallRecord>();
ArrayList<CallRecord> callingInLandRecords=new ArrayList<CallRecord>();
ArrayList<CallRecord> answerInCityRecords=new ArrayList<CallRecord>();
ArrayList<CallRecord> answerInProvinceRecords=new ArrayList<CallRecord>();
ArrayList<CallRecord> answerInLandRecords=new ArrayList<CallRecord>();
ArrayList<MessageRecord> sendMessageRecords=new ArrayList<MessageRecord>();
ArrayList<MessageRecord> receiveMessageRecords=new ArrayList<MessageRecord>();
public ArrayList<CallRecord> getCallingInCityRecords() {
return callingInCityRecords;
}
public void addCallingInCityRecords (CallRecord callRecord)
{
callingInCityRecords.add(callRecord);
}
public ArrayList<CallRecord> getCallingInProvinceRecords() {
return callingInProvinceRecords;
}
public void addCallingInProvinceRecords (CallRecord callRecord)
{
callingInProvinceRecords .add(callRecord);
}

public ArrayList<CallRecord> getCallingInLandRecords() {
return callingInLandRecords;
}
public void addCallingInLandRecords (CallRecord callRecord)
{
callingInLandRecords.add(callRecord);
}
public ArrayList<CallRecord> getAnswerInCityRecords() {
return answerInCityRecords;
}
public void addAnswerInCityRecords (CallRecord answerRecord)
{
answerInCityRecords.add(answerRecord);
}
public ArrayList<CallRecord> getAnswerInProvinceRecords() {
return answerInProvinceRecords;
}
public void addAnswerInProvinceRecords (CallRecord answerRecord)
{
answerInProvinceRecords.add(answerRecord);
}
public ArrayList<CallRecord> getAnswerInLandRecords() {
return answerInLandRecords;
}
public void addAnswerInLandRecords (CallRecord answerRecord)
{
answerInLandRecords.add(answerRecord);
}
public ArrayList<MessageRecord> getSendMessageRecords() {
return sendMessageRecords;
}
public void addSendMessageRecords (MessageRecord sendMessageRecord)
{
sendMessageRecords.add(sendMessageRecord);
}
public ArrayList<MessageRecord> getReceiveMessageRecords() {
return receiveMessageRecords;
}
public void addReceiveMessageRecords (MessageRecord receiveMessageRecord)
{
receiveMessageRecords.add(receiveMessageRecord);
这个题主要是做座机的收费较为局限性,只考虑座机的情况且只考虑打电话的情况。主要运用的ArrayList的使用,以及考察类的设计,但是给了类的设计图,把难度减少了许多。

实现南昌市电信分公司的计费程序,假设该公司针对手机和座机用户分别采取了两种计费方案,分别如下:
1、针对市内座机用户采用的计费方式(与电信计费系列1内容相同):
月租20元,接电话免费,市内拨打电话0.1元/分钟,省内长途0.3元/分钟,国内长途拨打0.6元/分钟。不足一分钟按一分钟计。
假设本市的区号:0791,江西省内各地市区号包括:0790~0799以及0701。
2、针对手机用户采用实时计费方式:
月租15元,市内省内接电话均免费,市内拨打市内电话0.1元/分钟,市内拨打省内电话0.2元/分钟,市内拨打省外电话0.3元/分钟,省内漫游打电话0.3元/分钟,省外漫游接听0.3元/分钟,省外漫游拨打0.6元/分钟;
注:被叫电话属于市内、省内还是国内由被叫电话的接听地点区号决定,比如以下案例中,南昌市手机用户13307912264在区号为020的广州接听了电话,主叫号码应被计算为拨打了一个省外长途,同时,手机用户13307912264也要被计算省外接听漫游费:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Scanner;

public class Main {

public static void main(String[] args) {
Scanner in = new Scanner(System.in);
ArrayList<User> users1 = new ArrayList<User>();
ArrayList<User> users2 = new ArrayList<User>();
ChargeMode chargeMode;
ArrayList<CallRecord> callRecords = new ArrayList<CallRecord>();
SimpleDateFormat df = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss");

String[] tokens = null;
Date time1=null,time2=null;
while(true)
{
String number=in.nextLine();
if(number.equals("end"))
break;
int f=0;
f=JudgeFormat.judge(number);
if(f!=0)
{
for(int i=0;i<number.length();i++)
{
tokens=number.split("[- ]");
}

if(tokens[0].equals("u")){//开户
CallRecord callRecord = new CallRecord();
String areaCode;
LandlinePhoneCharging m = new LandlinePhoneCharging();//座机
MobilePhoneCharging n =new MobilePhoneCharging();//手机
chargeMode = m;
chargeMode = n;
if(f==1)
{
boolean judge=true;
areaCode = tokens[1].substring(0, 4);
callRecord.setCallingAddressAreaCode(areaCode);//区号
for(User user : users1)
{
if(user.getNumber().equals(tokens[1]))//判断是否已开户
judge=false;
}
if(judge) {//如果没有就开户
User u = new User(m,tokens[1]);
users1.add(u);//开户
}
}
else if(f==2)
{
boolean judge=true;
for(User user : users2)
{
if(user.getNumber().equals(tokens[1]))//判断是否已开户
judge=false;
}
if(judge) {//如果没有就开户
User u = new User(n,tokens[1]);
users2.add(u);//开户
}
}
}

if(tokens[0].equals("t")) {
CallRecord callRecord = new CallRecord();
String anwserareaCode,callareaCode;
if(f==3)
{
callareaCode = tokens[1].substring(0, 4);//拨打区号
callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号
callRecord.setCallingNumber(tokens[1]);//传入拨打号码
anwserareaCode = tokens[2].substring(0, 4);//接通地址
callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号
callRecord.setAnswerNumber(tokens[2]);//传入接通号码
try {
time1 = df.parse(tokens[3]+" "+tokens[4]);
} catch (ParseException e1) {
e1.printStackTrace();
}

try {
time2 = df.parse(tokens[5]+" "+tokens[6]);
} catch (ParseException e) {
e.printStackTrace();
}

callRecord.setStartTime(time1);//开始时间
callRecord.setEndTime(time2);//结束时间
callRecords.add(callRecord);//添加用户记录
}

if(f==4)
{
callareaCode = tokens[1].substring(0, 4);//拨打区号
callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号
callRecord.setCallingNumber(tokens[1]);//传入拨打号码
anwserareaCode = tokens[3];//接通地址
callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号
callRecord.setAnswerNumber(tokens[2]);//传入接通号码
try {
time1 = df.parse(tokens[4]+" "+tokens[5]);
} catch (ParseException e1) {
e1.printStackTrace();
}

try {
time2 = df.parse(tokens[6]+" "+tokens[7]);
} catch (ParseException e) {
e.printStackTrace();
}

callRecord.setStartTime(time1);//开始时间
callRecord.setEndTime(time2);//结束时间
callRecords.add(callRecord);//添加用户记录
}

if(f==5)
{
callareaCode = tokens[2];//拨打区号
callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号
callRecord.setCallingNumber(tokens[1]);//传入拨打号码
anwserareaCode = tokens[4];//接通地址
callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号
callRecord.setAnswerNumber(tokens[3]);//传入接通号码
try {
time1 = df.parse(tokens[5]+" "+tokens[6]);
} catch (ParseException e1) {
e1.printStackTrace();
}

try {
time2 = df.parse(tokens[7]+" "+tokens[8]);
} catch (ParseException e) {
e.printStackTrace();
}

callRecord.setStartTime(time1);//开始时间
callRecord.setEndTime(time2);//结束时间
callRecords.add(callRecord);//添加用户记录
}

if(f==6)
{
callareaCode = tokens[2];//拨打区号
callRecord.setCallingAddressAreaCode(callareaCode);//传入拨打区号
callRecord.setCallingNumber(tokens[1]);//传入拨打号码
anwserareaCode = tokens[3].substring(0,4);//接通地址
callRecord.setAnswerAddressAreaCode(anwserareaCode);//传入接通区号
callRecord.setAnswerNumber(tokens[3]);//传入接通号码
try {
time1 = df.parse(tokens[4]+" "+tokens[5]);
} catch (ParseException e1) {
e1.printStackTrace();
}

try {
time2 = df.parse(tokens[6]+" "+tokens[7]);
} catch (ParseException e) {
e.printStackTrace();
}

callRecord.setStartTime(time1);//开始时间
callRecord.setEndTime(time2);//结束时间
callRecords.add(callRecord);//添加用户记录
}

}
}
}
// for(int i=0;i<callRecords.size();i++) {
// System.out.println(callRecords.get(i).getAnswerNumber()+" "+callRecords.get(i).getCallingNumber()+" "+callRecords.get(i).getCallingAddressAreaCode()+" "+callRecords.get(i).getAnswerAddressAreaCode());
// }
//

Collections.sort(users1,new Comparator<User>() {
public int compare(User s1,User s2){
double n1 = Double.parseDouble(s1.getNumber());
double n2 = Double.parseDouble(s2.getNumber());
if(n1 > n2) {
return 1;
}
return -1;
}

});
Collections.sort(users2,new Comparator<User>() {
public int compare(User s1,User s2){
double n1 = Double.parseDouble(s1.getNumber());
double n2 = Double.parseDouble(s2.getNumber());
if(n1 > n2) {
return 1;
}
return -1;
}

});

 在座机的基础上增加了手机,还有地区之分,比如市内打电话给省内,市内打电话给市内,市内打电话给省外等一系列的情况。好在没处理信息收费的情况,但是难度较于第一次还是有很大的提升。情况变得更复杂,就需要你的类的设计更加的合理,更有复用性,而且第一次如果不按照老师给的类图写,会比较难写。

三.踩坑心得

对于这几次作业的一个坑点,我觉得就是一开始要好好的读懂类图,然后通过类图去设计方法,这样比较方便也不会随意出错。要好好运用父类与子类的特点,这样可以减少重复的代码,提高写代码的效率,并且在后期维护或者说修改代码的时候可以方便很多。然后在类多了以后要清楚各个类的对象是否通用,很容易出错,或者是这个成员变量是否通用,要清楚父类与子类的关系。而且要清楚面向对象这个特点。

四.改进建议:

对于前这三次作业而言,我的代码一般都是大家的惯性思维,由于怕出错,所以都写得比较常规,有些题目确实有更简单的思路,但是我不知道怎么去运用哪些方法,可能是知识量储备的比较少吧。有不少是询问了同学之后才完成的。还有是对正则表达式认知的不到位,不知道怎么去正确使用正则表达式去筛选出输入格式错误的地方,如果将这个点弄明白的话,代码的复杂程度就会降低很多。而且其中还有不少是不按照常规方法写的,这对与后两次写的代码有点痛苦,不好续写。

五.总结

通过这三次的习题练习,我学到了挺多的东西。
比如说继承与多态,继承(inheritance) 机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础.上进行扩展,增加功能。这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结构。体现了由简单到复杂的认识过程。
多态性(polymorphism) 多态性是考虑在不同层次的类中,以及在同一类中,同名的成员函数之间的关系问题。函数的重载,运算符的重载,属于编译时的多态性。以虚基类为基础的运行时的多态性是面向对象程序设计的标志题。函数的重载,运算符的重载,属于编译时的多态性。以虚基类为基础的运行时的多态性是面向对象程序设计的标志。

子类与父类
子类和父类的概念是在继承中才会有的,继承的前提是 is-a 原则,比如:Student is a Person,那么我们就可以表示为Student extends Person。

子类又叫派生类,子类一定具有父类的全部属性与行为,并且拥有的属性更多,具体的行为更加丰富,表示的范围更小;父类又名超类。

子类对象在进行实例化之前一定会首先实例化父类对象,先有父类对象才有子类对象,即先调用父类的构造方法之后再调用子类构造方法!
子类在继承父类时会继承父类的所有结构 (包括私有属性、构造方法、普通方法)。。

最新文章

  1. Hibernate组件映射
  2. iOS判断数组不为空
  3. Android成长日记-使用PagerAdapter实现页面切换
  4. 在没装VS2010的机器上运行VS2010开发的C++程序
  5. hdu 1715 大菲波数 高精度和运算,水
  6. hdu 4006/AvlTree
  7. js jquery学习
  8. MT9v024总结
  9. 【转】android UI进阶之实现listview中checkbox的多选与记录--不错
  10. xib和Storyboard 创建Cell的方式
  11. C#代码模拟http发送get和post请求
  12. GCC中初始化函数是怎样被处理的?
  13. Cocos2d-x项目总结中的一些遇到的问题
  14. BZOJ 4108: [Wf2015]Catering [上下界费用流]
  15. ASP.NETMVC 分页
  16. Xamarin 开发过的那些项目
  17. ECharts折线图多个折线每次只显示一条
  18. Topshelf:一款非常好用的 Windows 服务开发框架 转发https://www.cnblogs.com/happyframework/p/3601995.html
  19. 让NotePad++添加到右键快捷方式
  20. Lodop打印控件中PRINT_INITA()和PRINT_PAGESIZE()宽高

热门文章

  1. vue项目element-ui组件打包后组件显示方框解决方式
  2. 获取网页数据 Qt 从客户端发起http响应
  3. 单文件WSDL,非模块化
  4. tomcat各个版本下载
  5. Angular+FileSaver实现导出(xlsx或ExcelJS)
  6. S32DS中链接文件及启动代码学习
  7. 关于decimal与double数据类型
  8. ZSTUOJ刷题⑥:Problem 3535.--模拟简单计算器
  9. python+scrcpy实现将安卓设备录屏并保存到pc本地
  10. Java 基础(二)