Blog作业02
一、前言
从题目集4到题目集6运用到的知识点主要是类的聚合、继承、封装、多态以及对正则表达式的运用;题目集4的题量不多但每道题难度较大,在题目集5之前,老师通过一次调查,在题目集5和题目集6将题目量加大,但题目难度下降,对我来说我更喜欢第二种模式。
总的来说,改变模式后题目量以及题目难度更合适。
二、设计与分析
①第四次题目集7-2与第五次题目集7-5:
7-2:
这题主要知识点是对类的聚合进行运用。
设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

- 在主类中通过switch语句来选择需要进行的功能;
代码:
switch(a) {
case 1:
int n1 = input.nextInt();
if(!dateUtil.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
dateUtil.getNextNDays(n1);
System.out.println(dateUtil.showDate());
break;
case 2:
int n2 = input.nextInt();
if(!dateUtil.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
dateUtil.getPreviousNDays(n2);
System.out.println(dateUtil.showDate());
break;
case 3:
int year_ = input.nextInt();
int month_ = input.nextInt();
int day_ = input.nextInt();
if((year_<1900||year_>2050)||(month_<1||month_>12)||(day_<1||day_>31)){
System.out.println("Wrong Format");
System.exit(0);
}
if(!dateUtil.checkInputValidity()) {
System.out.println("Wrong Format");
System.exit(0);
}
dateUtil.setDay_(day_);
dateUtil.setMonth_(month_);
dateUtil.setYear_(year_);
int num = dateUtil.getDaysofDates();
System.out.println(num);
break;
default :
System.out.println("Wrong Format");
System.exit(0);
}
2.定义类DateUtil、Day、Month、Year,在类在DateUtil中创建类Day的对象,在类Month中创建类Year的对象;
代码:




3.类DateUtil中判检验数据合法性、输出下n天或前n天的日期以及求下下n天、前n天、两日期的天数差。
代码:




4.在类Day中返回这个月的最大天数,在类Year中判断是否是闰年;
代码:




小结:本题主要考察对类的聚合关系,在刚开始时不太理解题目中的聚合,不知道如何通过第一个类一步一步get下一个类,后来通过与同学探讨学会。总的来说,如果理解了这题的类图题目就不会很难。通过这题我对类的聚合关系更加了解。
7-5:
这题与第四次题目集7-2题目几乎一样,只是将类的聚合关系改变。
设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

1.这题与题目集四7-2不同的是在类DateUtil中创建类Day、Month、Year的对象;
代码:

2.与题目集四7-2不同的地方还有就是将求下n天以及求前n天的方法进行改进,在题目集四7-2中是一天一天的推算,而这题中是先一年一年的算,当n小于366时再一天一天的推算。这样修改的好处是当n特别大时,代码的运行更快。
代码:


3.除了以上两点不同,其他部分几乎一样;

小结:这题在题目集四7-2的基础上进行修改,主要修改是类之间聚合关系,题目集四7-2中是一个类聚合另一个类,但题目集五7-5中是类Day、Month、Year共同聚合于类DateUtil。
第四次题目集7-2与第五次题目集7-5的聚合优劣比较:
- 第四次题目集7-2中每个类之间的关系太过紧密,导致耦合度太大。而第五次题目集7-5中每个类只与第一个类有关系。
- 第五次题目集7-5中类的复用性大大增强。
②第四次题目集7-3与第六次题目集7-5、7-6:
7-3:
编写程序,实现图形类的继承,并定义相应类对象并进行测试。
类图:

- 类Shape,无属性,有一个返回0.0的求图形面积的公有方法public double getArea();//求图形面积
2.类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继 承来的求面积方法,求圆的面积

3.类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继
承来的求面积方法,求矩形的面积
4.类Ball,继承自Circle,其属性从父类继承,重写父类求面积方法,求球表面
积,此外,定义一求球体积的方法public double getVolume();//求球体积

5.类Box,继承自Rectangle,除从父类继承的属性外,再定义一个属性height,
重写父类继承来的求面积方法,求立方体表面积,此外,定义一求立方体体积的方
public double getVolume();//求立方体体积

- 注意:
- 每个类均有构造方法,且构造方法内必须输出如下内容:Constructing 类名
- 每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
- 输出的数值均保留两位小数

7.主方法内,主要实现四个功能(1-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;
假如数据输入非法(包括圆、矩形、球及立方体对象的属性不大于0和输入选择值非1-4),系统输出Wrong Format



小结:这题考察的知识点主要是类的继承,通过这次题学会了如何输出保留两位小数、利用Super来调用父类中的属性;另外对类的继承更了解了。
7-5:
从盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出Wrong Format。
如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
- 各个图形的面积;
- 所有图形的面积总和;
- 排序后的各个图形面积;
- 再次所有图形的面积总和。
类图:

1.先输入三个整数,分别代表要创建各个图像对象的个数,用ArrayList<Shape>来存储各个图形对象;
代码:


2.抽象类Shape,包括抽象方法getArea()、validate()和String toString();
代码:

3.类Circle,继承自Shape,有一个私有实型的属性radius(半径),重写父类继承来的求面积方法,求圆的面积;
代码:

4.类Rectangle,继承自Shape,有两个私有实型属性width和length,重写父类继承来的求面积方法,求矩形的面积;
代码:
5.类Triangle,继承自Shape,有三个私有属性side1、side2、side3,重写父类继承来的求面积方法,求三角形面积;
代码:


6.保留两位小数输出所求面积,并将面积排序后再次输出。
代码:



小结:这题在第四次题目集7-3的基础上增加了运用多态的知识,提高了代码的可复用性,另外这题的类充分体现了类的独立性;通过这个题目学会了如何利用Collections.sort根据动态数组ArrayList<Shape>中对象的某一个属性来进行排序,对类的多态熟练运用。
7-6:
编写程序,使用接口及类实现多态性,类图结构如下所示:

- 增加一个父类Shape,方法getArea(),用来返回图像面积;
代码:

2.类Circle,继承于类Shape,私有属性有radius,表示圆的半径,重写父类的方法getArea() ,求圆的面积;
代码:

3.类Rectangle,继承于类Shape,私有属性有width和length,表示矩形的长和宽,重写父类的方法getArea() ,求矩形的面积;
代码:

4.接口GetArea,有一个抽象方法getArea();类Circle和类Rectangle实现该接口;
代码:


小结:这题在类的封装、继承、多态的基础上又增加了一个接口,通过这题让我学会了如何让类来实现接口;
③三次题目集中用到的正则表达式技术的分析总结:
- 题目集四7-1:水文数据校验及处理
在这题中主要运用到正则表达式在判断输入是否为空,判断测量时间、目标水位、实际水位、开度、流量是否合法;
代码:
public boolean vaildateMeasureDateTime(String measureDateTime) {
Pattern p =Pattern.compile("((([1-9]{1}|[1-9][0-9]{1}
|[1-9][0-9]{2}|[1-9][0-9]{3})"+"/((([13578]|1[02])/([1-9]|[12][0-9]|3[01]))|
(([469]|11)/([1-9]|[12][0-9]|30))"+ "|(2/([1-9]|[1][0-9]|2[0-8]))))|
((([1-9]{0,1}[0-9]{0,1})(0[48]|
[2468][048]|[13579][26])"+ "|((0[48]|[2468][048]|[3579][26])00))/2/29)) ([02468]|1[02468]|2[02]):00");
return p.matcher(measureDateTime).matches();
}
public boolean WaterLever(String waterLever) {
Pattern p = Pattern.compile("[1-9]\\d{0,2}
(\\.\\d{1,3})?");
return p.matcher(waterLever).matches();
}
public boolean GateOpening(String gateOpening) {
Pattern p = Pattern.compile("[1-9]\\.\\d{2}");
return p.matcher(gateOpening).matches();
}
2.题目集五7-4:统计Java程序中关键词的出现次数
这题对正则表达式的主要运用体现在对字符串进行字符替换以及对特定字符串的捕获;
代码:
str = str.replaceAll("(//.*)","*");
str = str.replaceAll("(/\\*{1,2}[\\s\\S]*?\\*/)","*");
str = str.replaceAll("\\\"([^\\\"]*)\\\"","*");
str = str.replaceAll(","," ");
str = str.substring(1,str.length()-2);
if(str.matches("^\\s*|\\s*$")) {
System.out.println("Wrong Format");
System.exit(0);
}
str = str.replace("["," ");
str = str.replace("]"," ");
for(int i = 0;i < s.length;i++) {
int num = 0;
Pattern p = Pattern.compile("\\b"+s[i]+"\\b");
Matcher m = p.matcher(str);
while(m.find()) {
num++;
}
if(num != 0) {
System.out.println(num + " " + s[i]);
}
}
3.题目集六7-1、7-3、7-4:正则表达式训练-QQ号校验、验证码校验、学号校验
这三题对正则表达式的考察较简单,都是对一个字符串进行检验。
代码:
7-1:

7-3:

7-4:

总结:三次题目集对正则表达式的运用让我学会了运用正则表达式和replace来对字符串进行替换操作,同时还学会了对字符串的特定子字符串进行匹配、捕获。
④题目集5(7-4)中Java集合框架应用的分析总结:
在这题中运用了List接口来存储输入的源码;List集合代表一个有序集合,集合中每一个元素都有其对应的顺序索引。List集合允许运用重复元素,可以通过索引来访问指定的集合元素。
List特有的常见方法:
(1)、添加
void add(int Index , E element):在list的指定位置插入元素
void addAll(int index , Collection<? Extends E> e):将指定collection中的所有元素插入到列表中的指定位置
(2)、删除
E remove(int Index):删除指定位置的元素,并返回该元素;
(3)、修改
E set(int index , E element):替换指定位置的元素,并返回被替换的元素
(4)、获取
Int indexOf(Object o):返回指定元素第一次出现的索引,如果该list中不含则返回-1;
E get(int Index):返回指定位置的元素;
三、采坑心得
题目集四7-1:
- 当输入的某一条数据中有多个错误时,先输出错误所在行和列最后输出这一条数据;当时是直接遇到错误就会输出整行数据,导致多次输出。
- 在利用正则表达式时忘记在前面加上/。
题目集四7-2:
1.题目要求的是每个类一次聚合,刚开始时我没有理解,误写成年月日三个类聚合于第一个类。
2.在计算前n天以及后n天时每次都会出现几天的差异,后来把每次推算后的日期输出发现在2月每次都是29天。后来在代码中加上了一个方法专门返回上一个月的最大天数。
题目集五7-4:
1.刚开始时的想法是把每一行分割放在数组中,后来发现如果注释连续两行或多行时无法准确用replace去除。改进后是直接将整个进行字符串操作。
2.在输入是没有在每一行之间加上”\n”,导致出现以下错误:

题目集五7-5:
题目中的一个测试点是求某一天的下n(int型最大值)天,由于数字太大导致代码运行超时。后来将原来的一天天的循环改为先一年年的计算,但n减小到小于366时,再来一天天的循环。
四、改进建议
- 对于复杂正则表达式的运用还不是很熟练。还要对正则表达式继续学习。
- 有很多知识点在写题时不会,需要花时间现在网上学习。
- 对于类的多态还是不熟练,在后续学习对这个方面还要在网上学习、理解。
- 有些代码的圈复杂度超过20,在后面的作业迭代中尽量减少圈复杂度。
五、总结
1.通过题目集四7-1开始学习对正则表达式的学习,对正则表达式有一定的了解,认识到正则表达式对字符串处理的方便。
2.通过题目集四7-2和7-3对类的继承与类之间聚合关系更加熟练,能够清楚的运用。
3.通过题目集五7-4学习到了正则表达式对字符串进行匹配和捕获。
4.通过题目集六7-5开始学习类的多态,在写完这道题目时对类的多态有了更深的理解。
5.通过题目集六7-6学会了接口,在接口中写一个抽象方法并用其他类去实现它。

浙公网安备 33010602011771号