第二次博客作业
一、前言(对三次题目集的总结)
相比于前三次作业集,这三次作业集的难度可以说有了一个比较大的提升,同时知识点也变多了。但总体来说,这三次题目集的难度成下降趋势。更有利于基础的学习。
1.题目集四:第四次题目集一共有三道题,题目不多,但是题目的难度较大。第一题是对水文数据的校验与处理,这里主要考察正则表达式对所输入的数据进行检验。包括对数据的处理和输入输出。这里也考察到了对类的定义与使用,以及怎么编写类合适来完成程序的功能。第二题是对日期问题的聚合。这题难度不大,主要考察类与类之间的聚合关系,这需要对聚合有很清晰的认识才能够对整个程序有清晰的逻辑。其次还有Day,Month,Year类中定义各个属性还有方法。包括基本的属性和无参,有参构造方法和其他方法。再有日期的计算方法。第三题是图形继承,主要考察类与类之间的继承关系。以及各种图形对父类的求面积方法的复写,用new的对象调用类中的方法输出,难度较低。
2.题目集五:第五次题目集共有五题,难度中等,第一题考察对字符串的处理即split方法的使用和对字符串长度的判断。第二题考察数组的合并和排序,Arrays.sort方法的使用。第三题是对整型数据进行排序,考察了选择排序法,冒泡排序法,插入排序法这三种基本排序方法。第四题是统计Java程序中关键词的出现次数,考察对Java关键字的检验与匹配,对List,Map接口,以及源码输入和结果输出。第五题是日期聚合的另一种形式,考察了类与类之间的聚合关系和日期的计算方法。
3.第六次题目集一共有6道题,难度较易,其中前4题中有三题是对正则表达式的运用,有一题是对字符串的考察。包括Pattern和 Matcher的用法以及正则表达式如何匹配所要匹配的QQ号,验证码,学号和对字符串的排序,对ASCII码的认识。第五题是图形的继承与多态,主要考察类与类之间的继承与多态的运用,对数组Arraylist的定义和其方法add,get的使用,还有对象数组的使用。类的定义与方法的定义,关键字extends的使用。String.format方法对数据输出格式的要求。第六题是实现图形接口和多态性,主要考察接口的定义interface implements abstract的使用以及类对接口中抽象方法的复写与实现,还有类多态的使用。整体难度较中等,题量较少,知识点考察较为复杂全面。
二、设计与分析
①
题目集四7-2:设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
题目集五7-5:设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
代码如下
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int num = input.nextInt(); switch (num) { case 1: int y1 = input.nextInt(); int m1 = input.nextInt(); int d1 = input.nextInt(); int n1 = input.nextInt(); DateUtil date1 = new DateUtil(y1,m1,d1); if(!date1.checkInputValidity()||n1<0) { System.out.print("Wrong Format"); }else { System.out.print(y1 + "-" + m1 + "-" + d1 + " next " + n1 + " days is:"); System.out.println(date1.getNextNDays(n1).showDate()); }break; case 2: int y2 = input.nextInt(); int m2 = input.nextInt(); int d2 = input.nextInt(); int n2 = input.nextInt(); DateUtil date2 = new DateUtil(y2,m2,d2); if(!date2.checkInputValidity()||n2<0) { System.out.print("Wrong Format"); }else { System.out.print(y2 + "-" + m2 + "-" + d2 + " previous " + n2 + " days is:"); System.out.println(date2.getPreviousDays(n2).showDate()); }break; case 3: int y3 = input.nextInt(); int m3 = input.nextInt(); int d3 = input.nextInt(); int y4 = input.nextInt(); int m4 = input.nextInt(); int d4 = input.nextInt(); DateUtil date3 = new DateUtil(y3,m3,d3); DateUtil date4 = new DateUtil(y4,m4,d4); if(!date3.checkInputValidity()||!date4.checkInputValidity()) { System.out.print("Wrong Format"); }else { System.out.println("The days between "+y3+"-"+m3+"-"+d3+" and "+y4+"-"+m4+"-"+d4+" are:"+date3.getDaysofDates(date4)); }break; default:System.out.print("Wrong Format"); } } } class DateUtil{ private Year year; private Month month; private Day day; int[] mon_maxnum = {31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil() { super(); // TODO Auto-generated constructor stub } public DateUtil(int y,int m,int d) { super(); this.year = new Year(y); this.month = new Month(m); this.day = new Day(d); } public Year getYear() { return year; } public void setYear(Year year) { this.year = year; } public Month getMonth() { return month; } public void setMonth(Month month) { this.month = month; } public Day getDay() { return day; } public void setDay(Day day) { this.day = day; } public void setDayMin() { this.day.setValue(1); } public void setDayMax() { if(this.year.isLeapYear()&&this.month.getValue()==2) { this.day.setValue(29); }else this.day.setValue(mon_maxnum[this.month.getValue()-1]); } public boolean checkInputValidity() { if(this.month.validate()&&this.year.validate()&&this.day.getValue()>=1) { if(this.year.isLeapYear()&&this.month.getValue()==2&&this.day.getValue()<=29) return true; else if(this.day.getValue()<=mon_maxnum[this.month.getValue()-1]) { return true; } } return false; } public DateUtil getNextNDays(int n){ for(long i = 0; i < n; i++) { if(this.year.isLeapYear()) mon_maxnum[1] = 29; else mon_maxnum[1] = 28; if(this.day.getValue()==mon_maxnum[this.month.getValue()-1]&&this.month.getValue()==12) { this.setDayMin(); this.month.monthIncrement(); this.year.yearIncrement(); } else if(this.day.getValue()==mon_maxnum[this.month.getValue()-1]) { setDayMin(); this.month.monthIncrement(); }else this.day.dayIncrement(); } return new DateUtil(this.year.getValue(),this.month.getValue(),this.day.getValue()); } public DateUtil getPreviousDays(int n) { for(long i =0; i < n; i++) { if(this.year.isLeapYear()) mon_maxnum[1] = 29; else mon_maxnum[1] = 28; if(this.day.getValue()==1&&this.month.getValue()==1) { this.year.yearReduction(); this.month.monthReduction(); setDayMax(); }else if(this.day.getValue()==1) { this.month.monthReduction(); setDayMax(); }else this.day.dayReduction(); } return new DateUtil(this.year.getValue(),this.month.getValue(),this.day.getValue()); } public boolean compareDates(DateUtil date) { int x = 0; int y = 0; x = this.year.getValue()*366+this.month.getValue()*31+this.day.getValue(); y = date.year.getValue()*366+date.month.getValue()*31+date.day.getValue(); if(x>y) return true; return false; } public boolean equalTwoDates(DateUtil date) { int x = 0; int y = 0; x = this.year.getValue()*366+this.month.getValue()*31+this.day.getValue(); y = date.year.getValue()*366+date.month.getValue()*31+date.day.getValue(); if(x==y) return true; return false; } public int getDaysofDates(DateUtil date) { int num1 = 0; int num2 = 0; int year1 = this.year.getValue(); int month1 = this.month.getValue(); int day1 = this.day.getValue(); int year2 = date.year.getValue(); int month2 = date.month.getValue(); int day2 = date.day.getValue(); for(int i = 1; i < year1; i++){ if(i%400==0||(i%4==0&&i%100!=0)){ num1 = num1 + 366; }else{ num1 = num1 + 365; } } if(year1%400==0||(year1%4==0&&year1%100!=0)) { switch(month1){ case 1:num1 = num1 + day1;break; case 2:num1 = num1 + 31 + day1;break; case 3:num1 = num1 + 60 + day1;break; case 4:num1 = num1 + 91 + day1;break; case 5:num1 = num1 + 121 + day1;break; case 6:num1 = num1 + 152 + day1;break; case 7:num1 = num1 + 182 + day1;break; case 8:num1 = num1 + 213 + day1;break; case 9:num1 = num1 + 244 + day1;break; case 10:num1 = num1 + 274 + day1;break; case 11:num1 = num1 + 305 + day1;break; case 12:num1 = num1 + 335 + day1;break; } }else { switch(month1){ case 1:num1 = num1 + day1;break; case 2:num1 = num1 + 31 + day1;break; case 3:num1 = num1 + 60-1 + day1;break; case 4:num1 = num1 + 91-1 + day1;break; case 5:num1 = num1 + 121-1 + day1;break; case 6:num1 = num1 + 152-1 + day1;break; case 7:num1 = num1 + 182-1 + day1;break; case 8:num1 = num1 + 213-1 + day1;break; case 9:num1 = num1 + 244-1 + day1;break; case 10:num1 = num1 + 274-1 + day1;break; case 11:num1 = num1 + 305-1 + day1;break; case 12:num1 = num1 + 335-1 + day1;break; } } for(int i = 1; i < year2; i++){ if(i%400==0||(i%4==0&&i%100!=0)){ num2 = num2 + 366; }else{ num2 = num2 + 365; } } if(year2%400==0||(year2%4==0&&year2%100!=0)) { switch(month2){ case 1:num2 = num2 + day2;break; case 2:num2 = num2 + 31 + day2;break; case 3:num2 = num2 + 60 + day2;break; case 4:num2 = num2 + 91 + day2;break; case 5:num2 = num2 + 121 + day2;break; case 6:num2 = num2 + 152 + day2;break; case 7:num2 = num2 + 182 + day2;break; case 8:num2 = num2 + 213 + day2;break; case 9:num2 = num2 + 244 + day2;break; case 10:num2 = num2 + 274 + day2;break; case 11:num2 = num2 + 305 + day2;break; case 12:num2 = num2 + 335 + day2;break; } }else { switch(month2){ case 1:num2 = num2 + day2;break; case 2:num2 = num2 + 31 + day2;break; case 3:num2 = num1 + 60-1 + day2;break; case 4:num2 = num2 + 91-1 + day2;break; case 5:num2 = num2 + 121-1 + day2;break; case 6:num2 = num2 + 152-1 + day2;break; case 7:num2 = num2 + 182-1 + day2;break; case 8:num2 = num2 + 213-1 + day2;break; case 9:num2 = num2 + 244-1 + day2;break; case 10:num2 = num2 + 274-1 + day2;break; case 11:num2 = num2 + 305-1 + day2;break; case 12:num2 = num2 + 335-1 + day2;break; } } return Math.abs(num1-num2); } public String showDate(){ return this.year.getValue() + "-" + this.month.getValue() + "-" + this.day.getValue(); } } class Day{ public Day() { super(); // TODO Auto-generated constructor stub } public Day(int value) { super(); this.value = value; } private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } public void dayIncrement() { this.value++; } public void dayReduction() { this.value--; } } class Month{ public Month() { super(); // TODO Auto-generated constructor stub } public Month(int value) { super(); this.value = value; } private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } public void resetMin(){ this.value = 1; } public void reseMax() { this.value = 12; } public boolean validate() { if(this.value>=1&&this.value<=12) return true; return false; } public void monthIncrement() { this.value++; if(!validate()) { resetMin(); } } public void monthReduction() { this.value--; if(!validate()) { reseMax(); } } } class Year{ public Year() { super(); // TODO Auto-generated constructor stub } public Year(int value) { super(); this.value = value; } private int value; public int getValue() { return value; } public void setValue(int value) { this.value = value; } public boolean isLeapYear(){ if(this.value%400==0||(this.value%4==0&&this.value%100!=0)){ return true; } return false; } public boolean validate() { if(this.value>=1820&&this.value<=2020) { return true; } return false; } public void yearIncrement() { this.value++; } public void yearReduction() { this.value--; } }
两次题目分析:
对比第四次题目集7-2和第五次题目集7-5,后者比前着的圈最大复杂度低。同时从内图中我们可以看出这两种解决这些问题到不同聚合方式。前者是Year类聚合到Month中,再把Month类聚合到Day类中之中,最后再用Dateutil类调用Day类,通过连接聚合的方式将各类联系起来。而在后者的类图中我们可以看到,它是将Year类,Month类,Day类共同聚合与Dateutil类之中从而达到类聚合的目的。两种不同的聚合方式,却可以解决相同的一个问题。同样的可以明显看出,后者的优异程度是明显大于前者的,首先就圈复杂度而言,后者远远低于前者,前者依赖于各类之间的连接,各类关系紧凑,容易出错,同时类与类之间的关系高度耦合,这就造成了程序过于僵硬,不能够灵活的变化;而后者采用多聚合的方式,更加符合迪米特原则,年月日三类之间互不干涉,因此其的类与类之间耦合度更低,大大的提高了代码的复用性和可扩展性。可以知道的是,后者的聚合方式是明显优于前者的。
②
题目集四(7-3):编写程序,实现图形类的继承,并定义相应类对象并进行测试。
- 类Shape,无属性,有一个返回0.0的求图形面积的公有方法
public double getArea();//求图形面积 - 类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积
- 类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积
- 类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面积,此外,定义一求球体积的方法
public double getVolume();//求球体积 - 类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方法
public double getVolume();//求立方体体积 - 注意:
- 每个类均有构造方法,且构造方法内必须输出如下内容:
Constructing 类名 - 每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
- 输出的数值均保留两位小数
主方法内,主要实现四个功能(1-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;
假如数据输入非法(包括圆、矩形、球及立方体对象的属性不大于0和输入选择值非1-4),系统输出Wrong Format
类图如下

代码如下
import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner input = new Scanner(System.in); int love = input.nextInt(); switch(love) { case 1: double radius = input.nextDouble(); if(radius<0) { System.out.println("Wrong Format"); break; } else { Circle circle = new Circle(); circle.setRadius(radius); System.out.println("Circle's area:"+String.format("%.2f", circle.getArea())); break; } case 2: double width = input.nextDouble(); double length = input.nextDouble(); if(width<0||length<0) { System.out.println("Wrong Format"); break; } else { Rectangle rectangle = new Rectangle(); rectangle.setLength(length); rectangle.setWidth(width); System.out.println("Rectangle's area:"+String.format("%.2f",rectangle.getArea())); break; } case 3: double radius1 = input.nextDouble(); if(radius1<0) { System.out.println("Wrong Format"); break; } else { Ball ball = new Ball(); ball.setRadius(radius1); System.out.println("Ball's surface area:"+String.format("%.2f",ball.getArea())); System.out.println("Ball's volume:"+String.format("%.2f",ball.getVolume())); break; } case 4: double length1 = input.nextDouble(); double width1 = input.nextDouble(); double height = input.nextDouble(); if(length1<0||width1<0||height<0) { System.out.println("Wrong Format"); break; } else { Box box = new Box(); box.setWidth(width1); box.setLength(length1); box.setHeight(height); System.out.println("Box's surface area:"+String.format("%.2f",box.getArea())); System.out.println("Box's volume:"+String.format("%.2f",box.getVolume())); break; } default: System.out.println("Wrong Format"); } } } class Shape{ public Shape() { super(); // TODO Auto-generated constructor stub System.out.println("Constructing Shape"); } public double getArea() { return 0.0; } } class Circle extends Shape{ private double radius; public Circle() { super(); // TODO Auto-generated constructor stub System.out.println("Constructing Circle"); } public Circle(double radius) { super(); this.radius = radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public double getArea() { return (double)(Math.PI*Math.pow(this.radius, 2)); } } class Rectangle extends Shape{ private double width; private double length; public Rectangle() { super(); // TODO Auto-generated constructor stub System.out.println("Constructing Rectangle"); } public Rectangle(double width, double length) { super(); this.width = width; this.length = length; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } public double getArea() { return (double)(this.width*this.length); } } class Ball extends Circle{ public Ball() { super(); // TODO Auto-generated constructor stub System.out.println("Constructing Ball"); } public Ball(double radius) { super(radius); // TODO Auto-generated constructor stub } public double getArea() { return (double)(4*Math.PI*Math.pow(this.getRadius(), 2)); } public double getVolume() { return (double)((4/3.0)*Math.PI*Math.pow(this.getRadius(), 3)); } } class Box extends Rectangle{ private double height; public Box() { super(); // TODO Auto-generated constructor stub System.out.println("Constructing Box"); } public Box(double width, double length) { super(width, length); // TODO Auto-generated constructor stub } public Box(double height) { super(); this.height = height; } public double getHeight() { return height; } public void setHeight(double height) { this.height = height; } public double getArea() { return (double)(this.height*this.getLength()*2+this.height*this.getWidth()*2+this.getLength()*this.getWidth()*2); } public double getVolume() { return (double)(this.height*this.getWidth()*this.getLength()); } }
题目集六(7-5):
输入格式:
从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出
Wrong Format。 - 如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
- 各个图形的面积;
- 所有图形的面积总和;
- 排序后的各个图形面积;
- 再次所有图形的面积总和。
类图如下:

代码如下:
import java.util.Arrays; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input = new Scanner(System.in); int n1 = input.nextInt(); int n2 = input.nextInt(); int n3 = input.nextInt(); if(n1<0||n2<0||n3<0){ System.out.print("Wrong Format"); return ; } double r,l,h,a,b,c; double sum = 0; double[] area = new double[n1+n2+n3]; Shape [] shapes = new Shape[n1 + n2 + n3]; for(int i = 0 ;i < n1; i++) { r = input.nextDouble(); shapes[i] = new Circle(r); } for(int i = n1;i < n1+n2; i++) { l = input.nextDouble(); h = input.nextDouble(); shapes[i] = new Rectangle(l,h); } for(int i = n1+n2; i < n1+n2+n3; i++) { a = input.nextDouble(); b = input.nextDouble(); c = input.nextDouble(); shapes[i] = new Triangle(a,b,c); } for(int i = 0; i < n1+n2+n3; i++) { if(!shapes[i].validate()) { System.out.print("Wrong Format"); return ; } } System.out.println("Original area:"); for(int i = 0; i < n1+n2+n3; i++) { area[i] = shapes[i].getArea(); sum = sum + shapes[i].getArea(); System.out.print(shapes[i].toString()); } System.out.println(""); System.out.println("Sum of area:"+String.format("%.2f", sum)); System.out.println("Sorted area:"); Arrays.sort(area); for(int i = 0; i < n1+n2+n3; i++) { System.out.print(String.format("%.2f",area[i])+" "); } System.out.println(""); System.out.println("Sum of area:"+String.format("%.2f", sum)); } } abstract class Shape{ public abstract double getArea(); public abstract boolean validate(); public abstract String toString(); } class Circle extends Shape{ public Circle(double radius) { super(); this.radius = radius; } public double radius; @Override public double getArea() { // TODO Auto-generated method stub return Math.PI*this.radius*this.radius; } @Override public boolean validate() { // TODO Auto-generated method stub if(this.radius<=0) return false; return true; } @Override public String toString() { // TODO Auto-generated method stub return String.format("%.2f", this.getArea())+" "; } } class Rectangle extends Shape{ public Rectangle(double width, double length) { super(); this.width = width; this.length = length; } public double width; public double length; @Override public double getArea() { // TODO Auto-generated method stub return this.length*this.width; } @Override public boolean validate() { // TODO Auto-generated method stub if(this.length<=0||this.width<=0) return false; return true; } @Override public String toString() { // TODO Auto-generated method stub return String.format("%.2f", this.getArea())+" "; } } class Triangle extends Shape{ public Triangle(double side1, double side2, double side3) { super(); this.side1 = side1; this.side2 = side2; this.side3 = side3; } public double side1; public double side2; public double side3; @Override public double getArea() { // TODO Auto-generated method stub double p = (this.side1+this.side2+this.side3)/2; return Math.sqrt(p* (p - this.side1) * (p - this.side2) * (p - this.side3)); } @Override public boolean validate() { // TODO Auto-generated method stub if(this.side1<=0||this.side2<=0||this.side3<=0||this.side1+this.side2<=this.side3||this.side1+this.side3<=this.side2||this.side2+this.side3<=this.side1) return false; return true; } @Override public String toString() { // TODO Auto-generated method stub return String.format("%.2f", this.getArea())+" "; } }
题目集六(7-6):编写程序,使用接口及类实现多态性,类图结构如下所示:

其中:
- GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;
- Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口
- 要求:在Main类的主方法中分别定义一个圆类对象及矩形类对象(其属性值由键盘输入),使用接口的引用分别调用圆类对象及矩形类对象的求面积的方法,直接输出两个图形的面积值。(要求只保留两位小数)
代码如下
import java.util.Scanner; public class Main{ public static void main(String args[]){ Scanner input = new Scanner(System.in); double r = input.nextDouble(); double l = input.nextDouble(); double h = input.nextDouble(); if(r<=0||l<=0||h<=0){ System.out.println("Wrong Format"); return ; } Circle cir = new Circle(r); Rectangle rec = new Rectangle(l,h); System.out.println(String.format("%.2f",cir.getArea())); System.out.println(String.format("%.2f",rec.getArea())); } } interface GetArea{ public double getArea(); } class Circle implements GetArea{ public Circle() { super(); // TODO Auto-generated constructor stub } public Circle(double radius) { super(); this.radius = radius; } public double radius; public double getArea() { // TODO Auto-generated method stub return Math.PI*this.radius*this.radius; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } } class Rectangle implements GetArea{ public Rectangle() { super(); // TODO Auto-generated constructor stub } public Rectangle(double width, double length) { super(); this.width = width; this.length = length; } public double width; public double length; public double getArea() { // TODO Auto-generated method stub return this.length*this.width; } public double getWidth() { return width; } public void setWidth(double width) { this.width = width; } public double getLength() { return length; } public void setLength(double length) { this.length = length; } }
三次作业分析比较:
如图所示,第四次题目集7-3,第六次题目集7-5,7-6,分别是对类与类之间的封装,继承,多态和接口等特性和技术的运用。第四次题目集7-3是图形的继承,首先通过定义一个父类Shape,里面有无参构造方法和一个GetArea()方法,无参构造方法中输出Shape类名,然后通过定义Circle,Rectangle,Ball,Box类继承父类Shape,再通过分别用private定义封装自己的属性和无参有参构造方法getter,setter方法,无参构造方法中分别输出本图形的类名,再复写父类的方法从而返回本图形的面积。在主类中通过选择求不同图形的面积。其圈最大复杂度较高。第六次题目集7-5中定义一个抽象类Shape,里面有GetArea(),validate(),toString()三种抽象方法。再定义Circle,Rectangle,Triangle继承抽象类Shape,在各个类中定义封装各自的属性和方法,最核心的是复写Shape类中的三个方法。在主类中通过new对象,并用向下转型实现多态转到Arraylist数组,从而形成对象数组,通过循环调用方法从而得出并输出结果。第六次题目集7-6用到了接口。其中圈复杂度较低。首先用interface定义Shape接口,其中有一个GetArea()的抽象方法。再定义Circle,Rectangle用关键字implements来实现接口,其中各自定义封装自己的属性和方法,通过复写从而实现接口中的抽象方法。这三题是对面向对象的三个特性封装,继承和多态的具体实现,以及抽象类和接口的实现,运用private,extends,abstract,interface,implements等关键字实现封装,继承,多态。
③正则表达式技术分析
三次题目集中对于正则表达式的题目难度不一,但是都可以归为一点。
首先是首先是对正则表达式的运用,需要import java.util.Pattern和import java.util.Matcher。然后再调用Pattern的compile方法输入自己所要匹配的字符串,接着用Matcher定义一个变量,并调用find()方法判断是否找到自己所要匹配的数据。如果找到了对所捕获的数据进行操作,如果没找到,进行相应操作。
其次正则表达式的运用实质上其实是便是对数据的检验和匹配,通过使用正则表达式,我们可以减少很多的if和else的语句使用,极大的简化了代码量。
对于正则表达式的学习,我还有着很大的提升空间,其实在使用中我便发现了自身的很多不足,比如对于括号的运用,不同的情况下使用括号会导致不一样的结果。
④题目集5(7-4)中Java集合框架应用的分析总结
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java中共有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
分析:
对于该题,是通过对所输入的源代码检测Java中所有的关键字并输出Java关键字的出现次数。通过定义一个Check类对所输入的源代码进行检测,其中对所输入的注释和字符串中的关键字不统计。通过使用list将各个代码存入一个数组集合中,并通过循环依次遍历,从而统计出关键字的数量。对该题的集合框架的运用为list,通过list存入数组然后进行检测从而得到检测结果。
三.踩坑心得
在这三次题目集中我遇到了如下问题:
1.首先,是对于类聚合之间关系的梳理,刚开始对于它们的概念十分模糊,Day,Month,Year类中 value的疑惑。其中方法对value的操作等等。这些需要对其进行深入理解。
2.再接着,是对类与类之间关系的理解,继承等,类的继承实际上也算是一种声明,是关联里的依赖,组合,还是聚合,继承,还有多态。他们的关系较为复杂,需要细细理解题目含义和类图所给的关系,从而做出正确关系的判断的运用。在提交时也会遇到各种问题,比如Arraylist数组的定义错误,接口,抽象方法的定义与实现的语法错误。这些都需要去注意。
3.对于细节处理也是一项值得注意的东西,如关键词extends, interface, implements关键词拼写错误,同时还有输出格式的问题,结果保留两位小数,忘了保留两位小数,还有超过内存限制,定义String类型数组时,数组的长度超过其最大限制,导致程序报错等等。
4。对于正则表达式的利用,可以使用官网上的一个平台,可以很好的帮助我们去学习它们。链接如下:https://regex101.com/
四.改进建议
还是之前那句话,一个代码最重要的便是类与类之间的耦合度情况,每一个类实现一个功能,对于一个代码而言,圈复杂度及其重要,这关系到一个代码的质量,因此尽量在写代码的时候减少它的耦合度,同时自身也要多加提高编程水平。
第四次题目集7-1:可以使用更加简便的正则表达式。
五、总结
这三次题目集的学习,我学到了很多,有了对类与类之间关系的了解,同时提高了Java的编程思维,懂得了从多种编程方式中去选择最佳的方案。
同时,我学会了定义类和类里面的属性和方法,private,public,protected的区别,类与类之间的关系包括关联(依赖,聚合,组合),继承,多态还有接口的定义。抽象方法的定义,复写与实现,接口的实现。日期的计算方法。正则表达式的运用,对所输入数据进行校验与匹配。字符串中split分割等各种方法,关键字interface,implements extends的使用。用类创建对象来引用类,如何调用类的属性和类的方法。
再接着,我复习了多种排序法的使用,如选择排序法,冒泡排序法,插入排序法等,都让我受益良多。
浙公网安备 33010602011771号