面向对象程序设计题目集7-9总结
面向对象程序设计第三次博客作业
题目集7~9的总结
//该blog的前言,设计与分析,采坑心得,改进建议为一个一个题目集进行分析
//总结是整体总结
1.第七次题目集:
前言:
我们面向对象程序设计的学习即将进入尾声,题目集7~9是最后的题目集作业。
第七次题目集有两道题目,分别是:图形卡片排序游戏、图形卡片分组游戏。
这次题目集主要需要我们掌握类的继承、多态性使用方法以及接口的应用,来实现对图形卡片的排序与分组。
(一)第七次题目集设计与分析:
- 7-1 图形卡片排序游戏
类图:

卡片大小排序游戏规则:考虑一款适合于小学生的卡片(Card)排序游戏,其规则为随机发放一些卡片给学生,卡片分为 四种形状:圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid),并给出各种 卡片的相应参数,要求学生能够迅速求出各卡片的面积大小然后将卡片按照其面积值从大到小进行排 序,同时求出所有卡片的面积之和。
在Card类中使用了CompareTo的方法:
class Card implements Comparable<Card>{ Card(){ } Shape shape; Card(Shape shape) { this.shape=shape; } public void setShape(Shape shape) { this.shape = shape; } public Shape getShape() { return shape; } @Override public int compareTo(Card o) { if(this.getShape().getArea()>=o.getShape().getArea()) { return 1; } else return -1; } }
在主函数利用:
ArrayList<Card> k=new ArrayList<Card>(); k.sort(Collections.reverseOrder());//运用compareTo降序
来进行对数组面积大小的排序。
结构分析:



程序代码较为复杂,深度一般。
题目集7(7-1)的设计分析总结
在主函数内设立两个ArrayList数组:
ArrayList<Integer> w=new ArrayList<>(); ArrayList<Card> k=new ArrayList<Card>();
int n=input.nextInt();
看输入的是多少,卡片分为 四种形状:圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid)
再输入对应的边长或半径等参数,在各自的类中算出面积,使用 Comparable 接口, 即在 Card 类中实现 Comparable 接口中的 CompareTo()方法。
然后将卡片按照其面积值从大到小进行排序,同时求出所有卡片的面积之和,再将各种值输出。
- 7-2 图形卡片分组游戏
类图:

沿袭作业 7-1,本次作业主要对卡片(Card)进行分组游戏,其规则为随机发放一些卡片给学生, 卡片仍然分为四种形状:圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid), 并给出各种卡片的相应参数,要求学生首先根据卡片类型将所有卡片进行分组(一个类型分为一组, 所以最多四组),然后能够对每组内的卡片根据面积值从大到小进行排序,同时求出该组内所有卡片 的面积之和,最后求出每组卡片面积之和中的最大值。
CompareTo()的方法不变,增加四个ArrayList数组:
ArrayList<Card> circle=new ArrayList<>(); ArrayList<Card> rectangle=new ArrayList<>(); ArrayList<Card> triangle=new ArrayList<>(); ArrayList<Card> trapezoid=new ArrayList<>();
将根据卡片类型将所有卡片进行分组,对每组内的卡片根据面积值从大到小进行排序,同时求出该组内所有卡片 的面积之和,最后求出每组卡片面积之和中的最大值。
主函数中运用:
circle.sort(Collections.reverseOrder());//运用compareTo降序 trapezoid.sort(Collections.reverseOrder()); triangle.sort(Collections.reverseOrder()); rectangle.sort(Collections.reverseOrder());
来逆序输出。
结构分析:



程序代码较为复杂,深度一般。
题目集7(7-2)的递进式设计分析总结
相对(7-1),在Shape类引入了
public String toString()、
String shapeName;
等存在
abstract class Shape{ Shape(){ } String shapeName; Shape(String shapeName) { this.shapeName=shapeName; } @Override public String toString() { return "Shape{" + "shapeName='" + shapeName + '\'' + '}'; } public void setShapeName(String shapeName) { this.shapeName = shapeName; } public String getShapeName() { return shapeName; } abstract public double getArea(); abstract public boolean validate(); }
圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid)全部继承自Shape类。
主函数设立四个数组,利用多态性:
ArrayList<Card> k=new ArrayList<Card>(); Circle circle = new Circle(r); Card card = new Card(circle); card.getShape().setShapeName("Circle"); //----------- Rectangle rectangle = new Rectangle(width, length); Card card = new Card(rectangle); card.getShape().setShapeName("Rectangle"); //----------- Triangle triangle = new Triangle(x, y, z); Card card = new Card(triangle); card.getShape().setShapeName("Triangle"); // Trapezoid trapezoid = new Trapezoid(x, y, z); Card card = new Card(trapezoid); card.getShape().setShapeName("Trapezoid"); k.add(card);
经过匹配,将各个数值加入不同ArrayList数组:
public static double device(ArrayList<Card> k) { int i=0; ArrayList<Card> circle=new ArrayList<>(); ArrayList<Card> rectangle=new ArrayList<>(); ArrayList<Card> triangle=new ArrayList<>(); ArrayList<Card> trapezoid=new ArrayList<>(); String t1="Circle"; String t2="Rectangle"; String t3="Triangle"; String t4="Trapezoid"; for (i=0;i<k.size();i++) { if(sence()) { if (Pattern.matches(t1, k.get(i).getShape().getShapeName())) { circle.add(k.get(i)); } if (Pattern.matches(t2, k.get(i).getShape().getShapeName())) { rectangle.add(k.get(i)); } if (Pattern.matches(t3, k.get(i).getShape().getShapeName())) { triangle.add(k.get(i)); } if (Pattern.matches(t4, k.get(i).getShape().getShapeName())) { trapezoid.add(k.get(i)); } } }
根据卡片类型将所有卡片进行分组,对每组内的卡片根据面积值从大到小进行排序,同时求出该组内所有卡片 的面积之和,最后求出每组卡片面积之和中的最大值。
题目7(7-2)是题目7(7-1)的进阶版本,将(7-1)的代码经过以上修改即可。
(二)第七次题目集采坑心得
7-1 图形卡片排序游戏的题目较为简单,除去在CompareTo的知识点了解不够的情况下,没有困难的地方。
7-2 图形卡片分组游戏有一个:
@Override public String toString() { return "Shape{" + "shapeName='" + shapeName + '\'' + '}'; }
这个地方一开始不知道怎么使用,查资料后才学会使用。
以及一开始以为The max area是指所有面积里最大的,最后才发现是所有分组之和的面积中最大的。
(三)第七次题目集改进建议
难度适中,需要较好的明白类的继承、多态性使用方法以及接口的应用,难度比较适合我们。
并没有需要改进的地方。
2.第八次题目集
前言:
第八次题目集只有一道题目,但这道题目比较难写。
是一道编写一个银行 ATM 机的模拟程序,能够完成用户的存款、取款以及查询余额功能的题目。
需要我们:注意本题目中的各实体类之间的关系,尤其是一对多的组合关系、对实体类的设计要做到单一职责原则,且不能缺少规定的实体类、编程时考虑面向对象中的封装性本题目中的应用以及是否有能够扩展的衍生需求。
(一)第八次题目集设计与分析:
- 7-1 ATM机类结构设计(一)
编写一个银行 ATM 机的模拟程序,能够完成用户的存款、取款以及查询余额功能。
类图:

题目集8ATM机仿真题目的设计思路分析总结
class CU是中国银联类,里面储存银行名字及各卡号开户人的姓名。
public String nm(Bank bank)储存各卡号开户人的姓名
public String bk(Bank bank)储存银行名字
class Card是银行卡类,在这个类中进行对银行卡密码的匹配及对ATM机号的匹配。
class Bank是银行类,进行存款取款和判断取款是否大于存款的操作。
public double checkmoney(Card card, String[] k, double[] money)用来检测存款与取款的关系。
class Account是账户类,进行判断银行卡号是否存在和引入各类中的所有判断是否成功和进行存款查询的功能。
其中:
String[] a= {"6217000010041315709","6217000010041315715","6217000010041315718","6217000010051320007","6222081502001312389",
"6222081502001312390","6222081502001312399","6222081502001312400","6222081502051320785","6222081502051320786"};
double[] money={10000.00,10000.00,10000.00,10000.00,10000.00,10000.00,10000.00,10000.00};
String[] r={"01","02","03","04","05","06"};
public String bk(Bank bank){
if(bank.getCard().getN()<=3)
{
return "中国建设银行";
}
return "中国工商银行";
}
public String nm(Bank bank){
if(bank.getCard().getN()<=2)
return "杨过";
else
if(bank.getCard().getN()<=3)
return "郭靖";
else
if(bank.getCard().getN()<=7)
return "张无忌";
else
return "韦小宝";
}
结构分析:


(二)第八次题目集采坑心得
多人多卡存取款及查询余额的测试点一直过不去,最后发现是分割字符串进字符数组时,
多余的空格未被吸收,需要改成以//s+的分割方式消去空格。
查询余额的测试点之前没想到具体的改进方法,后来加上提前跳出循环,采用continue的语句跳入下个循环进行解决。
其余测试点没有特别卡住的地方。
(三)第八次题目集改进建议
第八次题目集的难度偏难,类的设计的方式写起来比较复杂,测试点安排比较合理,没有太大问题,但整体难度偏难,
花费的时间比较长,是一次很好的锻炼机会。
但不希望将方法规定死了只能用类的设计来写,即使是用if-else的结构,在下一题目集的改动也不是很麻烦,希望能考虑到各种方法的适用性。
3.第九次题目集
前言:
第九次题目集是对第八次题目集的进一步扩展。
在第八次题目集的基础上,根据账户的不同,银行卡一般分为借记卡(针对借记账户)和信用卡(针对贷记账户) 两类,银行账户分为借记账户和贷记账户两种,其中,借记账户不能够透支取款,而贷记账户可以透支取款(可能需要支付手续费),且允许跨行办理相关业务。
多加了四个人物及对应的银行卡号的贷记账号,并收取手续费和增加贷款业务。
虽然只有一道题目,但难度较难,需要在上一题目集的基础上进行修改。
(一)第九次题目集设计与分析:
- 7-1 ATM机类结构设计(二)
编写一个银行 ATM 机的模拟程序,能够完成用户的取款以及查询余额功能。
类图:

题目集9ATM机仿真题目的设计思路分析总结
class CU是中国银联类,里面储存银行名字及各卡号开户人的姓名,增加张三丰、令狐冲、乔峰、洪七公等人。
public String nm(Bank bank)储存各卡号开户人的姓名
public String bk(Bank bank)储存银行名字
class Card是银行卡类,在这个类中进行对银行卡密码的匹配及对ATM机号的匹配。
class Bank是银行类,进行存款取款和判断取款是否大于存款的操作。
public double checkmoney(Card card, String[] k, double[] money)用来检测存款与取款的关系。
class Account是账户类,进行判断银行卡号是否存在和引入各类中的所有判断是否成功和进行存款查询的功能。
几乎与上一题目集没什么区别,改动在于:
public double checkmoney(Card card, String[] k, double[] money)中,加入
int num=Integer.parseInt(card.use(k,card.getN()));//此时ATM机的编号 if(card.getN()<=1) { if(m>money[0]) { cnt = 1;//透支 break; } else if(num<=4) money[0]=money[0]-m; else if(num<=6) money[0]=money[0]-m-m*0.03; else money[0]=money[0]-m-m*0.04; if(money[0]<0){ cnt=1;break; } setMoney(money); card.setMoney(money); }
借记账号分别求手续费。
以下是贷记账号分别求手续费:
if(card.getN()<=11){ if (m>=0&&money[8]-m<-50000) { cnt = 1; break; } if(money[8]-m>=0){ if(num<=4) money[8] = money[8] - m; else if(num<=6) money[8] = money[8] - m-m*0.03; else money[8] = money[8] - m-m*0.04; } else { if(money[8]>0) p=m-money[8]; else p=m; if(num<=4) money[8] = money[8] - m-p*0.05; else if(num<=6) money[8] = money[8] - m-m*0.03-p*0.05; else money[8] = money[8] - m-m*0.04-p*0.05; } setMoney(money); card.setMoney(money);
若cnt=1时,透支:
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
否则就:
return m;
再传入class Account中的
public void show()进行钱的存款与取款。
结构分析:


(二)第九次题目集采坑心得
在写第九次题目集的时候,往往没有搞清楚各部分的手续费究竟怎么扣,导致计算结果总是出错。
在写的过程中没有看清题目要求,将借记账号也变成了可以贷款的账号,然后一直进行修改,导致花费大量时间。
甚至出现忘记存款大于取款的条件,坑比较多。
(三)第九次题目集改进建议
该题目集中还存在测试点的问题,比如多次小额取款后,再取超额的钱,会超出范围显示值。
在不同的存款条件下也会出现越存越多的情况。
这些地方并没有设置为测试点,有较大的bug存在,希望下次能多增加一些测试点,将分数稍微分散。
--------------------总结------------------
①题目集7(7-1)、(7-2)两道题目的递进式设计分析总结:
题目集7(7-1):
在Card类中使用了CompareTo的方法:
class Card implements Comparable<Card>{
Card(){
}
Shape shape;
Card(Shape shape)
{
this.shape=shape;
}
public void setShape(Shape shape) {
this.shape = shape;
}
public Shape getShape() {
return shape;
}
@Override
public int compareTo(Card o) {
if(this.getShape().getArea()>=o.getShape().getArea())
{
return 1;
}
else
return -1;
}
}
在主函数利用:
ArrayList<Card> k=new ArrayList<Card>();
k.sort(Collections.reverseOrder());//运用compareTo降序
来进行对数组面积大小的排序。
在主函数内设立两个ArrayList数组:
ArrayList<Integer> w=new ArrayList<>();
ArrayList<Card> k=new ArrayList<Card>();
int n=input.nextInt();
看输入的是多少,卡片分为 四种形状:圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid)
再输入对应的边长或半径等参数,在各自的类中算出面积,使用 Comparable 接口, 即在 Card 类中实现 Comparable 接口中的 CompareTo()方法。
然后将卡片按照其面积值从大到小进行排序,同时求出所有卡片的面积之和,再将各种值输出。
题目集7(7-2):
相对(7-1),在Shape类引入了
public String toString()、
String shapeName;
等存在
abstract class Shape{
Shape(){
}
String shapeName;
Shape(String shapeName)
{
this.shapeName=shapeName;
}
@Override
public String toString() {
return "Shape{" +
"shapeName='" + shapeName + '\'' +
'}';
}
public void setShapeName(String shapeName) {
this.shapeName = shapeName;
}
public String getShapeName() {
return shapeName;
}
abstract public double getArea();
abstract public boolean validate();
}
圆形(Circle)、矩形(Rectangle)、三角形(Triangle)及梯形(Trapezoid)全部继承自Shape类。
主函数设立四个数组,利用多态性:
ArrayList<Card> k=new ArrayList<Card>();
Circle circle = new Circle(r);
Card card = new Card(circle);
card.getShape().setShapeName("Circle");
//-----------
Rectangle rectangle = new Rectangle(width, length);
Card card = new Card(rectangle);
card.getShape().setShapeName("Rectangle");
//-----------
Triangle triangle = new Triangle(x, y, z);
Card card = new Card(triangle);
card.getShape().setShapeName("Triangle");
//
Trapezoid trapezoid = new Trapezoid(x, y, z);
Card card = new Card(trapezoid);
card.getShape().setShapeName("Trapezoid");
k.add(card);
经过匹配,将各个数值加入不同ArrayList数组:
public static double device(ArrayList<Card> k)
{
int i=0;
ArrayList<Card> circle=new ArrayList<>();
ArrayList<Card> rectangle=new ArrayList<>();
ArrayList<Card> triangle=new ArrayList<>();
ArrayList<Card> trapezoid=new ArrayList<>();
String t1="Circle";
String t2="Rectangle";
String t3="Triangle";
String t4="Trapezoid";
for (i=0;i<k.size();i++)
{
if (Pattern.matches(t1, k.get(i).getShape().getShapeName()))
{
circle.add(k.get(i));
}
if (Pattern.matches(t2, k.get(i).getShape().getShapeName()))
{
rectangle.add(k.get(i));
}
if (Pattern.matches(t3, k.get(i).getShape().getShapeName()))
{
triangle.add(k.get(i));
}
if (Pattern.matches(t4, k.get(i).getShape().getShapeName()))
{
trapezoid.add(k.get(i));
}
}
根据卡片类型将所有卡片进行分组,对每组内的卡片根据面积值从大到小进行排序,同时求出该组内所有卡片 的面积之和,最后求出每组卡片面积之和中的最大值。
题目7(7-2)是题目7(7-1)的进阶版本,将(7-1)的代码经过以上修改即可。
②题目集8和题目集9两道ATM机仿真题目的设计思路分析总结
题目集8:
class CU是中国银联类,里面储存银行名字及各卡号开户人的姓名。
public String nm(Bank bank)储存各卡号开户人的姓名
public String bk(Bank bank)储存银行名字
class Card是银行卡类,在这个类中进行对银行卡密码的匹配及对ATM机号的匹配。
class Bank是银行类,进行存款取款和判断取款是否大于存款的操作。
public double checkmoney(Card card, String[] k, double[] money)用来检测存款与取款的关系。
class Account是账户类,进行判断银行卡号是否存在和引入各类中的所有判断是否成功和进行存款查询的功能。
其中:
String[] a= {"6217000010041315709","6217000010041315715","6217000010041315718","6217000010051320007","6222081502001312389",
"6222081502001312390","6222081502001312399","6222081502001312400","6222081502051320785","6222081502051320786"};
double[] money={10000.00,10000.00,10000.00,10000.00,10000.00,10000.00,10000.00,10000.00};
String[] r={"01","02","03","04","05","06"};
public String bk(Bank bank){
if(bank.getCard().getN()<=3)
{
return "中国建设银行";
}
return "中国工商银行";
}
public String nm(Bank bank){
if(bank.getCard().getN()<=2)
return "杨过";
else
if(bank.getCard().getN()<=3)
return "郭靖";
else
if(bank.getCard().getN()<=7)
return "张无忌";
else
return "韦小宝";
}
题目集9:
class CU是中国银联类,里面储存银行名字及各卡号开户人的姓名,增加张三丰、令狐冲、乔峰、洪七公等人。
public String nm(Bank bank)储存各卡号开户人的姓名
public String bk(Bank bank)储存银行名字
class Card是银行卡类,在这个类中进行对银行卡密码的匹配及对ATM机号的匹配。
class Bank是银行类,进行存款取款和判断取款是否大于存款的操作。
public double checkmoney(Card card, String[] k, double[] money)用来检测存款与取款的关系。
class Account是账户类,进行判断银行卡号是否存在和引入各类中的所有判断是否成功和进行存款查询的功能。
几乎与上一题目集没什么区别,改动在于:
public double checkmoney(Card card, String[] k, double[] money)中,加入
int num=Integer.parseInt(card.use(k,card.getN()));//此时ATM机的编号
if(card.getN()<=1)
{
if(m>money[0]) {
cnt = 1;//透支
break;
}
else if(num<=4)
money[0]=money[0]-m;
else if(num<=6)
money[0]=money[0]-m-m*0.03;
else
money[0]=money[0]-m-m*0.04;
if(money[0]<0){
cnt=1;break;
}
setMoney(money);
card.setMoney(money);
}
借记账号分别求手续费。
以下是贷记账号分别求手续费:
if(card.getN()<=11){
if (m>=0&&money[8]-m<-50000)
{
cnt = 1;
break;
}
if(money[8]-m>=0){
if(num<=4)
money[8] = money[8] - m;
else if(num<=6)
money[8] = money[8] - m-m*0.03;
else
money[8] = money[8] - m-m*0.04;
}
else
{
if(money[8]>0)
p=m-money[8];
else
p=m;
if(num<=4)
money[8] = money[8] - m-p*0.05;
else if(num<=6)
money[8] = money[8] - m-m*0.03-p*0.05;
else
money[8] = money[8] - m-m*0.04-p*0.05;
}
setMoney(money);
card.setMoney(money);
若cnt=1时,透支:
System.out.println("Sorry,your account balance is insufficient.");
System.exit(0);
否则就:
return m;
再传入class Account中的
public void show()进行钱的存款与取款。
总的来说,这三次题目集的题目量都不多,但是对我们的技术掌握要求较高,题目偏难,需要我们掌握类的继承、多态性使用方法以及接口的应用,面对小程序ATM的设计要沉得下心来编程,不能半途而废、要有耐心。综合运用所学的各种知识点完成ATM,并在此基础上不断加以改进,显然有一定
难度,但这极好地锻炼了我们的能力,也充分让我们明白了自身的不足,是一些非常好的题目集。
extra:
相关概念说明 :
⚫中国银联(China UnionPay):成立于 2002 年 3 月,是经国务院同意,中 国人民银行批准设立的中国银行卡联合组织,总部设于上海。主要负责建设和 运营全国统一的银行卡跨行信息交换网络、提供银行卡跨行信息交换相关的专 业化服务、管理和经营“银联”品牌、制定银行卡跨行交易业务规范和技术标 准。其包含多家银行机构。
⚫银行(Bank):是依法成立的经营货币信贷业务的金融机构,是商品货币经 济发展到一定阶段的产物。
⚫银行用户(User):能够在银行办理相应业务的用户。一个银行机构可以拥 有多个银行用户及多个银行账户,一个用户也可以在多个银行机构开立账户。
⚫银行账户(Account):客户在银行开立的存款账户、贷款账户、往来账户 的总称。一个银行用户可以拥有多个银行账户。
⚫银行卡(Card):经批准由商业银行(含邮政金融机构) 向社会发行的具有 消费信用、转账结算、存取现金等全部或部分功能的信用支付工具。一个银行 账户可以发行多张银行卡。
⚫ ATM(Automated Teller Machine),自动柜员机,因大部分用于取款,又 称自动取款机。它是一种高度精密的机电一体化装置,利用磁性代码卡或智能 卡实现金融交易的自助服务,代替银行柜面人员的工作。可提取现金、查询存 款余额、进行账户之间资金划拨、余额查询等工作。一般 ATM 机隶属于某一银 行机构。

浙公网安备 33010602011771号