第三次Blog作业总结03
第三次Blog作业总结03
一、前言:三次题目集的知识点、题量、难度等情况
题目集7-9
1、题目集7要求:掌握类的继承、多态性使用方法以及接口的应用
2、题目集8要求:重点考核类的封装性及类间关系设计(关联、组合及依赖),难度较大
3、题目集9要求:重点训练内容为抽象类、继承与多态
二、设计与分析:重点对题目的提交源码进行分析,可参考SourceMonitor的生成报表内容以及PowerDesigner的相应类图,要有相应的解释和心得(做到有图有真相),本次Blog必须分析的内容如下:
(1)题目集7(7-1) 图形卡片排序游戏:
输入格式:
- 首先,在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:
1 3 4 2 1 3 4 2 1 3 0 - 然后根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边不能组成三角形),则输出
Wrong Format。 - 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
- 排序前的各图形类型及面积,格式为
图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n,注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格; - 排序后的各图形类型及面积,格式同排序前的输出;
- 所有图形的面积总和,格式为
Sum of area:总面积值。
输入样例1:
在这里给出一组输入。例如:
1 5 3 2 0
输出样例1:
在这里给出相应的输出。例如:
Wrong Format
输入样例2:
在这里给出一组输入。例如:
4 2 1 3 0
3.2 2.5 0.4 2.3 1.4 5.6 2.3 4.2 3.5
输出样例2:
在这里给出相应的输出。例如:
The original list:
Trapezoid:1.14 Rectangle:3.22 Circle:98.52 Triangle:4.02
The sorted list:
Circle:98.52 Triangle:4.02 Rectangle:3.22 Trapezoid:1.14
Sum of area:106.91
输入样例3:
在这里给出一组输入。例如:
4 2 1 3 0
3.2 2.5 0.4 2.3 1.4 5.6 2.3 4.2 8.4
输出样例3:
在这里给出相应的输出。例如:
Wrong Format
设计思路分析总结 :
需应用到的知识:
- 继承、多态的应用;
- ArrayList泛型的应用方法
- Comparable接口及泛型的应用
- 单一职责原则的应用
- “开-闭”原则的应用
(1)将本次作业程序与作业 6-1 进行比较,尤其是排序算法的运用;
(2)在图形类的设计中,考虑面向对象设计原则中的“开-闭”原则的实现方法及其作用,思考假如游戏中再增加一种图形,本次设计是否能实现“开-闭”原则。
类图如下:

源码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Scanner;
public class Main {
public static Scanner input = new Scanner(System.in);
public static void main(String[] args){
ArrayList<Integer> list = new ArrayList<Integer>();
int num = input.nextInt();
while(num != 0){
if(num < 0 || num > 4){
System.out.println("Wrong Format");
System.exit(0);
}
list.add(num);
num = input.nextInt();
}
DealCardList dealCardList = new DealCardList(list);
if(!dealCardList.validate()){
System.out.println("Wrong Format");
System.exit(0);
}
dealCardList.showResult();
input.close();
}
}
class Card{
Shape shape;
Card(Shape shape){
this.shape=shape;
}
public void setShape(Shape Shape) {
this.shape=shape;
}
public Shape getShape() {
return shape;
}
}
class DealCardList{
ArrayList<Card> cardList=new ArrayList<Card>();
DealCardList(ArrayList<Integer> list){
for(int i=0;i<list.size();i++)
{
switch(list.get(i)) {
case 1:
{
double r=Main.input.nextDouble();
Circle circle=new Circle(r);
Card card=new Card(circle);
card.getShape().setShapeName("Circle");
cardList.add(card);
}
break;
case 2:{
double a=Main.input.nextDouble();
double b=Main.input.nextDouble();
Rectangle rectangle=new Rectangle(a,b);
Card card=new Card(rectangle);
card.getShape().setShapeName("Rectangle");
cardList.add(card);
}
break;
case 3: {
double a=Main.input.nextDouble();
double b=Main.input.nextDouble();
double c=Main.input.nextDouble();
Triangle triangle=new Triangle(a,b,c);
Card card=new Card(triangle);
card.getShape().setShapeName("Triangle");
cardList.add(card);
}
break;
case 4: {
double a=Main.input.nextDouble();
double b=Main.input.nextDouble();
double c=Main.input.nextDouble();
Traperoid traperoid=new Traperoid(a,b,c);
Card card=new Card(traperoid);
card.getShape().setShapeName("Trapezoid");
cardList.add(card);
}
break;
default: break;
}
}
}
public void cardSort() {
for(int k=0;k<cardList.size();k++)
for(int i=k+1;i<cardList.size();i++)
{
if(cardList.get(k).getShape().getArea()<cardList.get(i).getShape().getArea())
Collections.swap(cardList, k, i);
}
}
public boolean validate() {
for(int i=0;i<cardList.size();i++)
{if(!cardList.get(i).getShape().vaildate())
return false;}
return true;
}
public double getAllArea() {
double s=0;
for(int i=0;i<cardList.size();i++)
s=s+cardList.get(i).getShape().getArea();
return s;
}
public void showResult() {
System.out.println("The original list:");
for(int i=0;i<cardList.size();i++)
System.out.print(cardList.get(i).getShape().getShapeName()+":"+String.format("%.2f",cardList.get(i).getShape().getArea())+" ");
System.out.println();
System.out.println("The sorted list:");
cardSort();
for(int i=0;i<cardList.size();i++)
System.out.print(cardList.get(i).getShape().getShapeName()+":"+String.format("%.2f",cardList.get(i).getShape().getArea())+" ");
System.out.println();
System.out.println("Sum of area:"+String.format("%.2f",getAllArea()));
}
}
class Shape {
String shapeName;
Shape(){
}
Shape(String shapeName){
this.shapeName=shapeName;
}
public String getShapeName() {
return shapeName;
}
public void setShapeName(String shapeName) {
this.shapeName=shapeName;
}
public double getArea() {
return 0.0;
}
public boolean vaildate() {
return true;
}
}
class Circle extends Shape {
String shapeName;
double radius;
Circle(){
}
Circle(double radius){
this.radius=radius;
}
public double getArea() {
return Math.PI*radius*radius;
}
public boolean vaildate() {
boolean flag = false;
if(radius>0)
flag = true;
return flag;
}
}
class Rectangle extends Shape{
double width,length;
Rectangle (double width,double length){
this.width=width;
this.length=length;
}
public double getArea() {
return width*length;
}
public boolean vaildate() {
boolean flag = false;
if(width>0&&length>0)
flag = true;
return flag;
}
}
class Triangle extends Shape{
double side1,side2,side3;
Triangle(double side1,double side2,double side3){
this.side1=side1;
this.side2=side2;
this.side3=side3;
}
public double getArea() {
double c=(side1+side2+side3)/2;
double s=Math.sqrt(c*(c-side1)*(c-side2)*(c-side3));
return s;
}
public boolean vaildate() {
boolean flag = false;
if(side1+side2>side3&&side1+side3>side2&&side2+side3>side1)
flag = true;
return flag;
}
}
class Traperoid extends Shape{
double topSide,bottomSide,height;
Traperoid(double topSide,double bottomSide,double height){
this.bottomSide=bottomSide;
this.height=height;
this.topSide=topSide;
}
public double getArea() {
return (topSide+bottomSide)*height/2;
}
public boolean validate() {
boolean flag = false;
if(topSide>0&&bottomSide>0&&height>0)
flag = true;
return flag;
}
}
输出样例1:

输出样例2:

输出样例3:

(2)题目集7(7-2)图形卡片分组游戏:
输入格式:
- 在一行上输入一串数字(1~4,整数),其中,1代表圆形卡片,2代表矩形卡片,3代表三角形卡片,4代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如:
1 3 4 2 1 3 4 2 1 3 0 - 根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。
输出格式:
- 如果图形数量非法(<=0)或图形属性值非法(数值<0以及三角形三边不能组成三角形),则输出
Wrong Format。 - 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下:
- 排序前的各图形类型及面积,格式为
[图形名称1:面积值1图形名称2:面积值2 …图形名称n:面积值n ],注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格,在结束符“]”之前; - 输出分组后的图形类型及面积,格式为
[圆形分组各图形类型及面积][矩形分组各图形类型及面积][三角形分组各图形类型及面积][梯形分组各图形类型及面积],各组内格式为图形名称:面积值。按照“Circle、Rectangle、Triangle、Trapezoid”的顺序依次输出; - 各组内图形排序后的各图形类型及面积,格式同排序前各组图形的输出;
- 各组中面积之和的最大值输出,格式为
The max area:面积值。
输入样例1:
在这里给出一组输入。例如:
1 5 3 2 0
输出样例1:
在这里给出相应的输出。例如:
Wrong Format
输入样例2:
在这里给出一组输入。例如:
4 2 1 3 0
3.2 2.5 0.4 2.3 1.4 5.6 2.3 4.2 3.5
输出样例2:
在这里给出相应的输出。例如:
The original list:
[Trapezoid:1.14 Rectangle:3.22 Circle:98.52 Triangle:4.02 ]
The Separated List:
[Circle:98.52 ][Rectangle:3.22 ][Triangle:4.02 ][Trapezoid:1.14 ]
The Separated sorted List:
[Circle:98.52 ][Rectangle:3.22 ][Triangle:4.02 ][Trapezoid:1.14 ]
The max area:98.52
输入样例3:
在这里给出一组输入。例如:
2 1 2 1 1 3 3 4 4 1 1 1 2 1 0
2.3 3.5 2.5 4.5 2.1 2.6 8.5 3.2 3.1 3.6 8.5 7.5 9.1245 6.5 3.4 10.2 11.2 11.6 15.4 5.8 2.13 6.2011 2.5 6.4 18.65
输出样例3:
在这里给出相应的输出。例如:
The original list:
[Rectangle:8.05 Circle:19.63 Rectangle:9.45 Circle:21.24 Circle:226.98 Triangle:4.65 Triangle:29.80 Trapezoid:50.49 Trapezoid:175.56 Circle:105.68 Circle:14.25 Circle:120.81 Rectangle:16.00 Circle:1092.72 ]
The Separated List:
[Circle:19.63 Circle:21.24 Circle:226.98 Circle:105.68 Circle:14.25 Circle:120.81 Circle:1092.72 ][Rectangle:8.05 Rectangle:9.45 Rectangle:16.00 ][Triangle:4.65 Triangle:29.80 ][Trapezoid:50.49 Trapezoid:175.56 ]
The Separated sorted List:
[Circle:1092.72 Circle:226.98 Circle:120.81 Circle:105.68 Circle:21.24 Circle:19.63 Circle:14.25 ][Rectangle:16.00 Rectangle:9.45 Rectangle:8.05 ][Triangle:29.80 Triangle:4.65 ][Trapezoid:175.56 Trapezoid:50.49 ]
The max area:1601.31
输入样例4:
在这里给出一组输入。例如:
1 1 3 0
6.5 12.54 3.6 5.3 6.4
输出样例4:
在这里给出相应的输出。例如:
The original list:
[Circle:132.73 Circle:494.02 Triangle:9.54 ]
The Separated List:
[Circle:132.73 Circle:494.02 ][][Triangle:9.54 ][]
The Separated sorted List:
[Circle:494.02 Circle:132.73 ][][Triangle:9.54 ][]
The max area:626.75
设计思路分析总结 :
(1)类图如下:

(2)实现功能
⚫ 对各图形信息进行输入并输出;
⚫ 输入数据的正确性校验;
⚫ 对输入的图形按照图形类型进行分组并输出,分组原理如下图所示:

⚫ 对每组内的图形按照面积值降序排序并输出;
⚫ 求出每组内图形面积的总和;
⚫ 求出所有组的面积总和的最大值并输出。 (2)输入输出规则 2 / 5 ①输入规则 首先,在一行上输入一串数字(1~4,整数),其中,1 代表圆形卡片,2 代表矩形卡片,3 代表 三角形卡片,4 代表梯形卡片。各数字之间以一个或多个空格分隔,以“0”结束。例如: 1 3 4 2 1 3 4 2 1 3 0 然后根据第一行数字所代表的卡片图形类型,依次输入各图形的相关参数,例如:圆形卡片需要 输入圆的半径,矩形卡片需要输入矩形的宽和长,三角形卡片需要输入三角形的三条边长,梯形需要 输入梯形的上底、下底以及高。各数据之间用一个或多个空格分隔。 ②输出规则
⚫ 如果图形数量非法(<=0)或图形属性值非法(数值<0 以及三角形三边不能组成三角形), 则输出“Wrong Format”。
⚫ 如果输入合法,则正常输出,所有数值计算后均保留小数点后两位即可。输出内容如下: ➢ 排序前的各图形类型及面积,格式为“[图形名称 1:面积值 1 图形名称 2:面积值 2 …图形名称 n:面积值 n ]”,注意,各图形输出之间用空格分开,且输出最后存在一个用于分隔的空格, 在结束符“]”之前; ➢ 输出分组后的图形类型及面积,格式为“[圆形分组各图形类型及面积][矩形分组各图形类型 及面积][三角形分组各图形类型及面积][梯形分组各图形类型及面积]”,各组内格式为“图形 名称:面积值”。按照“Circle、Rectangle、Triangle、Trapezoid”的顺序依次输出; ➢ 各组内图形排序后的各图形类型及面积,格式同排序前各组图形的输出; ➢ 各组中面积之和的最大值输出,格式为“The max area:面积值”。
(3)源码如下:
import java.util.Scanner;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.TreeSet;
//Chulishuju类
class Chulishuju{
ArrayList<Card> cardList=new ArrayList<>();
double[] zs=new double[4];
public Chulishuju(ArrayList<Integer> c){
for (Integer a:c){
if (a==0){
break;
}
else {
switch (a) {
case 1 :
Card a1 = new Card(new Circle(Main.x.nextDouble()));
cardList.add(a1);
a1.getShape().setName("Circle");
break;
case 2 :
Card b1 = new Card(new Rectangle(Main.x.nextDouble(), Main.x.nextDouble()));
cardList.add(b1);
b1.getShape().setName("Rectangle");
break;
case 3 :
Card c1 = new Card(new Triangle(Main.x.nextDouble(), Main.x.nextDouble(), Main.x.nextDouble()));
cardList.add(c1);
c1.getShape().setName("Triangle");
break;
case 4 :
Card d1 = new Card(new Trapezoid(Main.x.nextDouble(), Main.x.nextDouble(), Main.x.nextDouble()));
cardList.add(d1);
d1.getShape().setName("Trapezoid");
break;
}
}
}
}
//判断数据是否合法
public boolean pdsfhf(){
boolean kp=true;
for (Card a:cardList){
if (!a.getShape().pdsfhf()){
kp=false;
break;
}
}
return kp;
}
//输出圆的数据并计算总面积
public void yuan(){
zs[0]=0;
System.out.print("[");
for (Card a:cardList){
if(a.getShape().getName().equals("Circle")){
System.out.print(a.getShape());
zs[0]=zs[0]+a.getShape().Mj();
}
}
System.out.print("]");
}
//输出矩形的数据并计算总面积
public void juxing(){
zs[1]=0;
System.out.print("[");
for (Card a:cardList){
if(a.getShape().getName().equals("Rectangle")){
System.out.print(a.getShape());
zs[1]=zs[1]+a.getShape().Mj();
}
}
System.out.print("]");
}
//输出三角形的数据并计算总面积
public void sanjiaoxing(){
zs[2]=0;
System.out.print("[");
for (Card a:cardList){
if(a.getShape().getName().equals("Triangle")){
System.out.print(a.getShape());
zs[2]=zs[2]+a.getShape().Mj();
}
}
System.out.print("]");
}
//输出梯形的数据并计算总面积
public void tixing(){
zs[3]=0;
System.out.print("[");
for (Card a:cardList){
if(a.getShape().getName().equals("Trapezoid")){
System.out.print(a.getShape());
zs[3]=zs[3]+a.getShape().Mj();
}
}
System.out.print("]");
}
//从大到小输出圆的数据
public void ypx(){
TreeSet<Card> kp = new TreeSet<>(cardList);
System.out.print("[");
for (Card a:kp){
if(a.getShape().getName().equals("Circle")){
System.out.print(a.getShape());
}
}
System.out.print("]");
}
//从大到小输出矩形的数据
public void jxpx(){
TreeSet<Card> kp = new TreeSet<>(cardList);
System.out.print("[");
for (Card a:kp){
if(a.getShape().getName().equals("Rectangle")){
System.out.print(a.getShape());
}
}
System.out.print("]");
}
//从大到小输出三角形的数据
public void sjxpx(){
TreeSet<Card> kp = new TreeSet<>(cardList);
System.out.print("[");
for (Card a:kp){
if(a.getShape().getName().equals("Triangle")){
System.out.print(a.getShape());
}
}
System.out.print("]");
}
//从大到小输出梯形的数据
public void txpx(){
TreeSet<Card> kp = new TreeSet<>(cardList);
System.out.print("[");
for (Card a:kp){
if(a.getShape().getName().equals("Trapezoid")){
System.out.print(a.getShape());
}
}
System.out.print("]");
}
//找出最大总面积
public double getMax(){
double max=0;
int i;
for (i=0;i<4;i++){
if(max<zs[i]){
max=zs[i];
}
}
return max;
}
public void show(){//输出
System.out.println("The original list:");
System.out.print("[");
for (Card a : cardList) {
System.out.print(a.getShape());
}
System.out.print("]");
System.out.println("\nThe Separated List:");
yuan();juxing();sanjiaoxing();tixing();
System.out.println("\nThe Separated sorted List:");
ypx();jxpx();sjxpx();txpx();
System.out.printf("\nThe max area:%.2f\n",getMax());
}
}
//Card类
class Card implements Comparable<Card>{
private Shape shape;
//创建无参构造方法
public Card() {
}
//创建带参构造方法
public Card(Shape shape) {
this.shape = shape;
}
//getter
public Shape getShape() {
return shape;
}
//setter
public void setShape(Shape shape) {
this.shape = shape;
}
public int compareTo(Card card) {
return -(int)(shape.Mj()-card.getShape().Mj());
}
}
//Shape类
abstract class Shape {
private String name;
//创建无参构造方法
public Shape() {
}
//创建带参构造方法
public Shape(String name) {
this.name = name;
}
//getter
public String getName() {
return name;
}
//setter
public void setName(String name) {
this.name = name;
}
//面积
public abstract double Mj();
//判断数据是否合法
public abstract boolean pdsfhf();
public String toString() {
return getName()+":"+String.format("%.2f ",Mj());
}
}
//Circle类
class Circle extends Shape{
private double r;
//创建无参构造方法
public Circle(){
}
//创建带参构造方法
public Circle(double r){
this.r=r;
}
//getter
public double getR(){
return r;
}
//setter
public void setR(double r){
this.r = r;
}
//判断数据是否合法
public boolean pdsfhf() {
return r>0;
}
//计算圆面积
public double Mj(){
double mj=Math.PI*r*r;
return mj;
}
}
//Rectangle类
class Rectangle extends Shape{
private double a,b;
//创建无参构造方法
public Rectangle(){
}
//创建带参构造方法
public Rectangle(double a, double b){
this.a=a;
this.b=b;
}
//getter
public double A(){
return a;
}
public double B(){
return b;
}
//setter
public void setA(double a){
this.a=a;
}
public void setB(double b){
this.b=b;
}
//判断数据是否合法
public boolean pdsfhf() {
return a>0&&b>0;
}
//计算矩形面积
public double Mj(){
return a*b;
}
}
//Triangle类
class Triangle extends Shape{
private double a;
private double b;
private double c;
//创建无参构造方法
public Triangle() {
}
//创建带参构造方法
public Triangle(double a, double b, double c){
this.a = a;
this.b = b;
this.c = c;
}
//getter
public double A(){
return a;
}
public double B(){
return b;
}
public double C(){
return c;
}
//setter
public void setA(double a){
this.a=a;
}
public void setB(double b){
this.b=b;
}
public void setC(double c){
this.c=c;
}
//判断数据是否合法
public boolean pdsfhf(){
Double[] bc=new Double[3];
bc[0]=a;bc[1]=b;bc[2]=c;
boolean z=true;
Arrays.sort(bc);
if(a<=0&&b<=0&&c<=0){
z=false;
}
else{
if(!(a+b>c)){
z=false;
}
}
return z;
}
//计算三角形面积
public double Mj(){
double s1,s2;
s1=(a+b+c)/2;
s2=Math.sqrt(s1*(s1-a)*(s1-b)*(s1-c));
return s2;
}
}
//Trapezoid类
class Trapezoid extends Shape{
private double c,b,h;
//创建无参构造方法
public Trapezoid() {
}
//创建带参构造方法
public Trapezoid(double c, double b, double h) {
this.c = c;
this.b = b;
this.h = h;
}
//getter
public double C(){
return c;
}
public double B(){
return b;
}
public double H(){
return h;
}
//setter
public void setC(double a){
this.c=c;
}
public void setB(double b){
this.b=b;
}
public void setH(double c){
this.h=h;
}
//判断数据是否合法
public boolean pdsfhf() {
return b>0&&c>0&&h>0;
}
//计算梯形面积
public double Mj() {
return (c+b)*h/2;
}
}
//主类
public class Main{
public static Scanner x = new Scanner(System.in);//在Main类中定义一个静态Scanner对象,这样在其它类中如果想要使用该对象进行输入,则直接使用Main.input.next...即可(避免采坑)
public static void main(String[] args){
ArrayList<Integer> xzlist = new ArrayList<>();
int xz;
xz=x.nextInt();
if (xz==0){
System.out.println("Wrong Format");
System.exit(0);
}
while (xz!=0){//循环输入第一行数据
if(xz>4||xz<0){//如果输入的数据不合法
System.out.println("Wrong Format");
System.exit(0);
}
xzlist.add(xz);
xz=x.nextInt();
}
//检查数据是否合法
Chulishuju chulishuju=new Chulishuju(xzlist);
if(!chulishuju.pdsfhf()){
System.out.println("Wrong Format");
System.exit(0);
}
chulishuju.show();
x.close();
}
}
(4)输出如下:
样例1:
![]()
样例2:

样例3:

样例4:

(3)题目集8ATM机类结构设计(一):
输入格式:
每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:
- 存款、取款功能输入数据格式:
卡号 密码 ATM机编号 金额(由一个或多个空格分隔), 其中,当金额大于0时,代表取款,否则代表存款。 - 查询余额功能输入数据格式:
卡号
输出格式:
①输入错误处理
- 如果输入卡号不存在,则输出
Sorry,this card does not exist.。 - 如果输入ATM机编号不存在,则输出
Sorry,the ATM's id is wrong.。 - 如果输入银行卡密码错误,则输出
Sorry,your password is wrong.。 - 如果输入取款金额大于账户余额,则输出
Sorry,your account balance is insufficient.。 - 如果检测为跨行存取款,则输出
Sorry,cross-bank withdrawal is not supported.。
②取款业务输出
输出共两行,格式分别为:
[用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
③存款业务输出
输出共两行,格式分别为:
[用户姓名]在[银行名称]的[ATM编号]上存款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
④查询余额业务输出
¥[金额]
金额保留两位小数。
输入样例1:
在这里给出一组输入。例如:
6222081502001312390 88888888 06 -500.00
#
输出样例1:
在这里给出相应的输出。例如:
张无忌在中国工商银行的06号ATM机上存款¥500.00
当前余额为¥10500.00
输入样例2:
在这里给出一组输入。例如:
6217000010041315709 88888888 02 3500.00
#
输出样例2:
在这里给出相应的输出。例如:
杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥6500.00
输入样例3:
在这里给出一组输入。例如:
6217000010041315715
#
输出样例3:
在这里给出相应的输出。例如:
¥10000.00
输入样例4:
在这里给出一组输入。例如:
6222081502001312390 88888888 06 -500.00
6222081502051320786 88888888 06 1200.00
6217000010041315715 88888888 02 1500.00
6217000010041315709 88888888 02 3500.00
6217000010041315715
#
输出样例4:
在这里给出相应的输出。例如:
张无忌在中国工商银行的06号ATM机上存款¥500.00
当前余额为¥10500.00
韦小宝在中国工商银行的06号ATM机上取款¥1200.00
当前余额为¥8800.00
杨过在中国建设银行的02号ATM机上取款¥1500.00
当前余额为¥8500.00
杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥5000.00
¥5000.00
设计思路分析总结 :
(1)类图如下:
![]()
(2)实现功能
⚫ 基础数据的初始化;
⚫ 用户存款、取款及查询余额功能。
(3)初始化数据

(3)输入输出规则
1)输入规则 每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业 务操作输入格式如下: ➢ 存款、取款功能输入数据格式 卡号 密码 ATM 机编号 金额(由一个或多个空格分隔) 其中,当金额大于 0 时,代表取款,否则代表存款。 ➢ 查询余额功能输入数据格式 卡号
2)输出规则
①输入错误处理 如果输入卡号不存在,则输出“Sorry,this card does not exist.”。 如果输入 ATM 机编号不存在,则输出“Sorry,the ATM's id is wrong.”。 如果输入银行卡密码错误,则输出“Sorry,your password is wrong.”。 如果输入取款金额大于账户余额,则输出“Sorry,your account balance is insufficient.”。 如果检测为跨行存取款,则输出“Sorry,cross-bank withdrawal is not supported.”。
②取款业务输出 输出共两行,格式分别为: [用户姓名]在[银行名称]的[ATM 编号]上取款¥[金额] 当前余额为¥[金额] 其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
③存款业务输出 输出共两行,格式分别为: [用户姓名]在[银行名称]的[ATM 编号]上存款¥[金额] 当前余额为¥[金额] 其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
④查询余额业务输出 ¥[金额] 金额保留两位小数
(4)源码如下:
importjava.util.ArrayList; import java.util.Scanner; import java.util.Iterator; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); UnionPay unionPay = new UnionPay(); Bank ccb = new Bank("1001","中国建设银行"); Bank icbc = new Bank("1002","中国工商银行"); unionPay.addBank(ccb); unionPay.addBank(icbc); ATM aTM1 = new ATM("01",ccb); ATM aTM2 = new ATM("02",ccb); ATM aTM3 = new ATM("03",ccb); ATM aTM4 = new ATM("04",ccb); ATM aTM5 = new ATM("05",icbc); ATM aTM6 = new ATM("06",icbc); ccb.addATM(aTM1); ccb.addATM(aTM2); ccb.addATM(aTM3); ccb.addATM(aTM4); icbc.addATM(aTM5); icbc.addATM(aTM6); User Yangguo = new User("360101200102122324","杨过","13856223254"); User Guojing = new User("360101200012302552","郭靖","13800021124"); User Zhangwuji = new User("360502199805163221","张无忌","13952110011"); User Weixiaobao = new User("360201200513243326","韦小宝","13025996587"); Account ccbAcc1 = new Account("3217000010041315709",10000.00,Yangguo,ccb); Account ccbAcc2 = new Account("3217000010041315715",10000.00,Yangguo,ccb); Account ccbAcc3 = new Account("3217000010051320007",10000.00,Guojing,ccb); Account icbcAcc1 = new Account("3222081502001312389",10000.00,Zhangwuji,icbc); Account icbcAcc2 = new Account("3222081502001312390",10000.00,Zhangwuji,icbc); Account icbcAcc3 = new Account("3222081502001312399",10000.00,Zhangwuji,icbc); Account icbcAcc4 = new Account("3222081502051320785",10000.00,Weixiaobao,icbc); Account icbcAcc5 = new Account("3222081502051320786",10000.00,Weixiaobao,icbc); ccb.addAccount(ccbAcc1); ccb.addAccount(ccbAcc2); ccb.addAccount(ccbAcc3); icbc.addAccount(icbcAcc1); icbc.addAccount(icbcAcc2); icbc.addAccount(icbcAcc3); icbc.addAccount(icbcAcc4); icbc.addAccount(icbcAcc5); Yangguo.addAccount(ccbAcc1); Yangguo.addAccount(ccbAcc2); Guojing.addAccount(ccbAcc3); Zhangwuji.addAccount(icbcAcc1); Zhangwuji.addAccount(icbcAcc2); Zhangwuji.addAccount(icbcAcc3); Weixiaobao.addAccount(icbcAcc4); Weixiaobao.addAccount(icbcAcc5); Card ccbCard1 = new Card("6217000010041315709","88888888",ccbAcc1); Card ccbCard2 = new Card("6217000010041315715","88888888",ccbAcc1); Card ccbCard3 = new Card("6217000010041315718","88888888",ccbAcc2); Card ccbCard4 = new Card("6217000010051320007","88888888",ccbAcc3); Card icbcCard5 = new Card("6222081502001312389","88888888",icbcAcc1); Card icbcCard6 = new Card("6222081502001312390","88888888",icbcAcc2); Card icbcCard7 = new Card("6222081502001312399","88888888",icbcAcc3); Card icbcCard8 = new Card("6222081502001312400","88888888",icbcAcc3); Card icbcCard9 = new Card("6222081502051320785","88888888",icbcAcc4); Card icbcCard10 = new Card("6222081502051320786","88888888",icbcAcc5); ccbAcc1.addCard(ccbCard1); ccbAcc1.addCard(ccbCard2); ccbAcc2.addCard(ccbCard3); ccbAcc3.addCard(ccbCard4); icbcAcc1.addCard(icbcCard5); icbcAcc2.addCard(icbcCard6); icbcAcc3.addCard(icbcCard7); icbcAcc3.addCard(icbcCard8); icbcAcc4.addCard(icbcCard9); icbcAcc5.addCard(icbcCard10); StringBuilder sb = new StringBuilder(); String data; while(!((data = input.nextLine()).equals("#"))) { sb.append(data + "\n"); } String[] dt = sb.toString().split("\n"); for(int i = 0; i < dt.length; i++) { String[] dataLine = dt[i].toString().split("\\s+"); if(dataLine.length == 1) { GetBalance gb = new GetBalance(unionPay); System.out.println(String.format("¥%.2f", gb.getBalance(dataLine[0]))); }else { Withdraw wd = new Withdraw(unionPay,dataLine[0],dataLine[1],dataLine[2],Double.parseDouble(dataLine[3])); wd.withdraw(); } } } } class Bank { private String bankNO; private String bankName; private ArrayList<Account> accountList = new ArrayList<Account>(); private ArrayList<ATM> ATMList = new ArrayList<ATM>(); public Bank() { super(); // TODO Auto-generated constructor stub } public Bank(String bankNO, String bankName) { super(); this.bankNO = bankNO; this.bankName = bankName; } public String getBankNO() { return bankNO; } public void setBankNO(String bankNO) { this.bankNO = bankNO; } public String getBankName() { return bankName; } public void setBankName(String bankName) { this.bankName = bankName; } public void addAccount(Account account) { this.accountList.add(account); } public void removeAccount(Account account) { this.accountList.remove(account); } public void addATM(ATM aTM) { this.ATMList.add(aTM); } public void removeATM(ATM aTM) { this.ATMList.remove(aTM); } public ArrayList<Account> getAccountList() { return accountList; } public void setAccountList(ArrayList<Account> accountList) { this.accountList = accountList; } public ArrayList<ATM> getATMList() { return ATMList; } public void setATMList(ArrayList<ATM> aTMList) { ATMList = aTMList; } } class User { private String ID; private String name; private String Phone; ArrayList<Account> list = new ArrayList<Account>(); public User() { super(); // TODO Auto-generated constructor stub } public User(String iD, String name, String phone) { super(); ID = iD; this.name = name; Phone = phone; } public String getID() { return ID; } public void setID(String iD) { ID = iD; } public String getPhone() { return Phone; } public void setPhone(String phone) { Phone = phone; } public String getName() { return name; } public void setName(String name) { this.name = name; } public void addAccount(Account account) { this.list.add(account); } public void removeAccount(Account account) { this.list.remove(account); } } class Account { private String accountNO; private double balance = 0; private User user = null; private Bank bank = null; private static ArrayList<Card> list = new ArrayList<Card>(); public Account() { super(); // TODO Auto-generated constructor stub } public Account(String accountNO, double balance, User user, Bank bank) { super(); this.accountNO = accountNO; this.balance = balance; this.user = user; this.bank = bank; } public void addCard(Card card) { list.add(card); } public void removeCard(Card card) { list.remove(card); } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public String getAccountNO() { return accountNO; } public void setAccountNO(String accountNO) { this.accountNO = accountNO; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Bank getBank() { return bank; } public void setBank(Bank bank) { this.bank = bank; } public ArrayList<Card> getList() { return list; } public void setList(ArrayList<Card> list) { Account.list = list; } public static Account getAmountbyCardNO(String cardNO) { Iterator<Card> cardItr = Account.list.iterator(); Card card = null; while(cardItr.hasNext()) { card = cardItr.next(); if(card.getCardNO().equals(cardNO)) { return card.getAccount(); } } return null; } } class Card { private String cardNO; private String cardPassword; private Account account = null; public Card() { super(); // TODO Auto-generated constructor stub } public Card(String cardNO, String cardPassword, Account account) { super(); this.cardNO = cardNO; this.cardPassword = cardPassword; this.account = account; } public String getCardNO() { return cardNO; } public void setCardNO(String cardNO) { this.cardNO = cardNO; } public String getCardPassword() { return cardPassword; } public Account getAccount() { return account; } public void setAccount(Account account) { this.account = account; } public void setCardPassword(String cardPassword) { this.cardPassword = cardPassword; } public boolean checkCard() { Pattern p = Pattern.compile("\\d{16}+"); Matcher m = p.matcher(this.cardNO); return m.matches(); } public boolean checkPassword(String password) { return this.cardPassword.equals(password); } } class ATM { private String ATMID; private Bank bank = null; public ATM() { super(); // TODO Auto-generated constructor stub } public ATM(String aTMID, Bank bank) { super(); ATMID = aTMID; this.bank = bank; } public String getATMID() { return ATMID; } public void setATMID(String aTMID) { ATMID = aTMID; } public Bank getBank() { return bank; } public void setBank(Bank bank) { this.bank = bank; } } class Withdraw { private UnionPay unionPay; private String cardNO; private String cardPassword; private String ATMID; private double amount; public Withdraw() { super(); // TODO Auto-generated constructor stub } public Withdraw(UnionPay unionPay, String cardNO, String cardPassword, String aTMID, double amount) { super(); this.unionPay = unionPay; this.cardNO = cardNO; this.cardPassword = cardPassword; ATMID = aTMID; this.amount = amount; } public Withdraw(String cardNO, String cardPassword, String aTMID, double amount) { super(); this.cardNO = cardNO; this.cardPassword = cardPassword; ATMID = aTMID; this.amount = amount; } public void withdraw() { /** * 校验该卡是否存在 */ Card card = ValidateData.getCardbyCardNO(unionPay, cardNO); if(card == null) { System.out.println("Sorry,this card does not exist."); System.exit(0); } /** * 校验ATM是否存在 */ ATM aTM = ValidateData.getATMbyATMID(unionPay, ATMID); if(aTM == null) { System.out.println("Sorry,the ATM's id is wrong."); System.exit(0); } Account account = Account.getAmountbyCardNO(cardNO); double balance = account.getBalance(); /** * 校验卡密码是否正确 */ if(!card.getCardPassword().equals(cardPassword)) { System.out.println("Sorry,your password is wrong."); System.exit(0); } /** * 校验取款金额是否大于余额 */ if (amount > balance) { System.out.println("Sorry,your account balance is insufficient."); System.exit(0); } /** * 校验是否为跨行取款 */ if (account.getBank().getBankNO() != aTM.getBank().getBankNO()) { System.out.println("Sorry,cross-bank withdrawal is not supported."); System.exit(0); } account.setBalance(balance - amount);//取款更新余额操作 if(amount >= 0) { showResult(account,1); }else { showResult(account,0); } } public void showResult(Account account,int flag) { String type = ""; if(flag == 1) { type = "取款"; }else { type = "存款"; amount *= -1; } String userName = account.getUser().getName(); String bankName = account.getBank().getBankName(); System.out.println(userName + "在" + bankName + "的" + ATMID + "号ATM机上" + type + String.format("¥%.2f", amount)); System.out.println("当前余额为" + String.format("¥%.2f", account.getBalance())); } } class ValidateData { /** * 校验卡号是否存在 * @param unionPay * @param cardNO * @return */ public static Card getCardbyCardNO(UnionPay unionPay,String cardNO) { Card card = null; Iterator<Bank> bankItr = unionPay.getBankList().iterator(); while(bankItr.hasNext()) { ArrayList<Account> accountList = bankItr.next().getAccountList(); Iterator<Account> accountItr = accountList.iterator(); while(accountItr.hasNext()) { ArrayList<Card> cardList = accountItr.next().getList(); Iterator<Card> cardItr = cardList.iterator(); while(cardItr.hasNext()) { card = cardItr.next(); if(card.getCardNO().equals(cardNO)) { return card; } } } } return null; } /** * 校验ATM ID是否存在 * @param unionPay * @param ATMID * @return */ public static ATM getATMbyATMID(UnionPay unionPay,String ATMID) { Iterator<Bank> bankItr = unionPay.getBankList().iterator(); Bank bank = null; ATM aTM = null; while(bankItr.hasNext()) { bank = bankItr.next(); Iterator<ATM> aTMItr = bank.getATMList().iterator(); while(aTMItr.hasNext()) { aTM = aTMItr.next(); if(aTM.getATMID().equals(ATMID)) { return aTM; } } } return null; } } class UnionPay { private ArrayList<Bank> bankList = new ArrayList<Bank>(); public UnionPay() { super(); // TODO Auto-generated constructor stub } public UnionPay(ArrayList<Bank> bankList) { super(); this.bankList = bankList; } public ArrayList<Bank> getBankList() { return bankList; } public void setBankList(ArrayList<Bank> bankList) { this.bankList = bankList; } public void addBank(Bank bank) { this.bankList.add(bank); } public void removeBank(Bank bank) { this.bankList.remove(bank); } } class GetBalance { private UnionPay unionPay; public GetBalance() { super(); // TODO Auto-generated constructor stub } public GetBalance(UnionPay unionPay) { super(); this.unionPay = unionPay; } public double getBalance(String cardNO) { return ValidateData.getCardbyCardNO(unionPay,cardNO).getAccount().getBalance(); } }
(5)输出如下:
样例1:
样例2:

样例3:

样例4:

(4)题目集9ATM机类结构设计(二):
输入格式:
每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:
- 取款功能输入数据格式:
卡号 密码 ATM机编号 金额(由一个或多个空格分隔) - 查询余额功能输入数据格式:
卡号
输出格式:
①输入错误处理
- 如果输入卡号不存在,则输出
Sorry,this card does not exist.。 - 如果输入ATM机编号不存在,则输出
Sorry,the ATM's id is wrong.。 - 如果输入银行卡密码错误,则输出
Sorry,your password is wrong.。 - 如果输入取款金额大于账户余额,则输出
Sorry,your account balance is insufficient.。
②取款业务输出
输出共两行,格式分别为:
业务:取款 [用户姓名]在[银行名称]的[ATM编号]上取款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
③查询余额业务输出
业务:查询余额 ¥[金额]
金额保留两位小数。
输入样例1:
在这里给出一组输入。例如:
6222081502001312390 88888888 06 500.00
#
输出样例1:
在这里给出相应的输出。例如:
业务:取款 张无忌在中国工商银行的06号ATM机上取款¥500.00
当前余额为¥9500.00
输入样例2:
在这里给出一组输入。例如:
6217000010041315709 88888888 06 3500.00
#
输出样例2:
在这里给出相应的输出。例如:
业务:取款 杨过在中国工商银行的06号ATM机上取款¥3500.00
当前余额为¥6395.00
输入样例3:
在这里给出一组输入。例如:
6217000010041315715
#
输出样例3:
在这里给出相应的输出。例如:
业务:查询余额 ¥10000.00
输入样例4:
在这里给出一组输入。例如:
6222081502001312390 88888888 01 500.00
6222081502051320786 88888888 06 1200.00
6217000010041315715 88888888 02 1500.00
6217000010041315709 88888888 02 3500.00
6217000010041315715
#
输出样例4:
在这里给出相应的输出。例如:
业务:取款 张无忌在中国建设银行的01号ATM机上取款¥500.00
当前余额为¥9490.00
业务:取款 韦小宝在中国工商银行的06号ATM机上取款¥1200.00
当前余额为¥8800.00
业务:取款 杨过在中国建设银行的02号ATM机上取款¥1500.00
当前余额为¥8500.00
业务:取款 杨过在中国建设银行的02号ATM机上取款¥3500.00
当前余额为¥5000.00
业务:查询余额 ¥5000.00
输入样例5:
在这里给出一组输入。例如:
6640000010045442002 88888888 09 3000
6640000010045442002 88888888 06 8000
6640000010045442003 88888888 01 10000
6640000010045442002
#
输出样例5:
在这里给出相应的输出,例如:
业务:取款 张三丰在中国农业银行的09号ATM机上取款¥3000.00
当前余额为¥6880.00
业务:取款 张三丰在中国工商银行的06号ATM机上取款¥8000.00
当前余额为¥-1416.00
业务:取款 张三丰在中国建设银行的01号ATM机上取款¥10000.00
当前余额为¥-11916.00
业务:查询余额 ¥-11916.00
设计思路分析总结:
(1)实现功能:
⚫ 基础数据的初始化;
⚫ 用户取款及查询余额功能。
(2)初始化数据
![]()

(3)业务假定
1)系统的测试用例均采用如上数据,且所有卡号密码默认为“88888888”,初始余额均为 10000 元。
2)手续费默认均从银行卡所对应的账户中自动扣除。
3)跨行业务手续费收取比例由 ATM 机隶属银行决定,例如,用户手持中国工商银行的银行卡在中国建设银行的 ATM 上进行取款操作,则手续费收取比例为
中国建设银行的相应比例,按初始化数据中的规定为取款金额的 2%。
4)跨行查询余额不收取手续费。
5)透支取款手续费由中国银联统一规定为 5%,最大透支金额均为 50000 元。
(4)输入输出规则
1)输入规则
每一行输入一次业务操作,可以输入多行,最终以字符#终止。具体每种业务操作输入格式如下:
➢ 取款功能输入数据格式
卡号 密码 ATM 机编号 金额(由一个或多个空格分隔)
➢ 查询余额功能输入数据格式
卡号
2)输出规则
①输入错误处理
如果输入卡号不存在,则输出“Sorry,this card does not exist.”。
如果输入 ATM 机编号不存在,则输出“Sorry,the ATM's id is wrong.”。
如果输入银行卡密码错误,则输出“Sorry,your password is wrong.”。
如果输入取款金额大于账户余额或者透支金额超过规定最大透支金额,
则输出“Sorry,your account balance is insufficient.”。
②取款业务输出
输出共两行,格式分别为:
业务:取款 [用户姓名]在[银行名称]的[ATM 编号]上取款¥[金额]
当前余额为¥[金额]
其中,[]说明括起来的部分为输出属性或变量,金额均保留两位小数。
③查询余额业务输出
业务:查询余额 ¥[金额]
金额保留两位小数。
(5)类图如下:
![]()
三、采坑心得:
(1)银联、银行、用户、账户、银行卡、ATM机必须是实体类
(2)使用了ArrayList,即意味着程序很少会出现for、while等循环语句
(3)这个题目其实就是雨刷程序的升级版(类变多了),其编程的思路是一样的,认真参考其中的用处。
(4)所谓的借记卡与信用卡的说法实际是针对用户的账户类型。
四、改进建议:
(1)题目集中应运用一对多的类的做法,例如类A与B之间是一对多的关系:
class A{
private ArrayList<B> list = new ArrayList<B>();
public void addB(B obj){
list.add(obj);
}
public void remove(B obj){
list.remove(obj);
}
}
class B{
public B(){
}
}
(2)

程序中切忌出现这种代码,这种代码完全没有扩展性和维护性。
用户的卡号是会变化的,如果一万张卡,那岂不是要写一万个case?一百万个呢? 所以设计很重要,希望自身认真思考,这就是面向对象的编程思想。
千万不要为了完成题目而去拼凑代码,这样做对于提高编程水平毫无意义。
五、总结:
对本阶段三次题目集的综合性总结,学到了类的继承、多态性使用方法以及接口的应用,类的封装性及类间关系设计(关联、组合及依赖),抽象类、继承与多态需要进一步学习及重点训练。
总结以下完成题目集前未熟练掌握的知识点:
1.抽象类和常规类一样,都有数据和方法,但是不能用new操作符创建抽象类的实例
2.非抽象类中不能包含抽象方法。如果抽象类的子类没有实现所有继承下来的父类抽象方法,就必须将该子类也定义为抽象类。
3.包含抽象方法的类必须是抽象类。但是,抽象类可以不包含抽象的方法。
4、一个接口可以继承一个或多个接口。
5.接口是一种与类相似的结构,只包含常量和抽象方法,以及默认方法和静态方法。接口在许多方面与抽象类很相近,但抽象类可以 包含数据域。
6.在Java中,接口被认为是一种特殊的类。就像常规类一样,每个接口都被编译为独立的字节码文件。
7.接口 java.lang.Comparable定义了compareTo方法。Java类库中的许多类都实现了Comparable。
8.接口 java.lang.Cloneable是一个标记接口。实现Cloneable接口的类的对象是可克隆的。
9.一个类仅能继承一个父类,但却可以实现一个或多个接口。
10.一个接口可以继承一个或多个接口。




浙公网安备 33010602011771号