完成了题目集4、5、6我收获了很多,也在写代码时掌握了很多新的知识,在做题目的过程中,我深刻的认识到了学习java是在不断的练习中进步的,对此我觉得我有必要对着一次的练习做一次总结与对题目进行必要的分析。
首先分析题目集4的7-2题,这道题的难度适中,但书写出来的代码较长。在写代码时首先应该了解题目要求,并且知道写出该题所需要的方法。该题要求设计几个类:DateUtil类、Year类、Month类、Day类,并附上年月日的取值范围,题目提供了以下相应的类图:
该题目的最大复杂度为15,偏高,需要改进。
应用程序共有三个功能:1.求下一天2.求前n天3.求两个日期相差的天数。首先我明确了写该题的主要方法是聚合。聚合是关联的一种特殊形式,代表了两个对象之间的归属关系。聚集对has-a关系进行建模。所有者对象称为聚集对象,它的类称为聚集类。而从属对象称为被聚集对象,他的类称为被聚集类。在该题中,Year类是被聚集类,Month类以及Day类是聚集类也是被聚集类,DateUtil类是聚集类。根据这个类图可以很好的明确该代码的思路。定义一个Year类,该类里面包含了yearValue以及Year的构造方法,其中还包括了判断输入的yearValue值得合法性以及判断yearValue值是否为闰年的方法。为了方便求下n天以及前n天还必须加入yearIncrement()方法 和yearReduction()方法,该段代码如下图所示:
class Year{ private int yearValue; Year(){} Year(int yearValue){ this.yearValue=yearValue; } int getYearValue(){ return yearValue; } void setYearValue(int yearValue){ this.yearValue=yearValue; } boolean isLeapYear(){ return (yearValue%400==0||(yearValue%4==0&&yearValue%100!=0)); } boolean validate(int yearValue){ if(yearValue<2051&&yearValue>=1900) return true; else return false; } void yearIncrement(){ yearValue++; } void yearReduction(){ yearValue--; } }
根据类图所示,类Month中含有Year类对象,在java代码中,可以通过使用数据域以及方法来实现关联,在Month类中包含Year类,故在Month类的数据域中写有private Year year=new Year(); 除此之外,较为重要的是访问Year对象的方法的书写以及改变Year对象的书写
Year getYear(){ return year; } void setYear(Year year){ this.year=year; }
当然,还得书写判断monthValue是否合法的相关代码,为了得到代码的主要功能还得有monthIncrement()方法和monthReduction()方法。与Month类相似,Day类方法的数据域中包含了Month类的对象:private Month month=new Month();
Month getMonth(){ return month; } void setMonth(Month month){ this.month=month; }
该代码与上诉代码几乎相同。定义dayValue值减少和值增加的方法
void dayIncrement(){ int days=month.getDayOfMonth(); if(dayValue<days) dayValue++; else{ dayValue=1; month.monthIncrement(); } } void dayReduction(){ if(dayValue>=2){ dayValue--; } else{ month.monthReduction(); dayValue=month.getDayOfMonth(); } }
书写完Year类、Month类以及Day类后,在DateUtil类中访问这些类中的方法可以通过该类中调用的某个特殊数据域方法来实现。在写该代码的过程中,我开始并不知道如何在DateUtil类中访问Day类中的方法以及在Month类中的方法、Year类中的方法。通过一次次的调试 以及询问老师我明白了可以通过例如使用Month的对象调用getYear方法获得Year对象再调用Year对象的setYear()方法来得带Year类中方法的使用,犹如洋葱一般一层层的深入,令人感到神奇。写到这里,该题的主要代码就完成的差不多了,接下来就要写求下n天以及前n天,两天之间相差的天数的主要代码了。
题目集5的7-4题也是有关面向对象设计日期问题的聚合类问题,题目要求大致相同,但看题目给出的类图却与上一题目集的不相同:
这里直接从DateUtil类中延伸出多个类:Month类、Year类和Day类,该题的写法与上一题的写法本质相同,但内容不同。上一题的类是一 类包含一类,比较有连贯性,但如果有某一类出现了bug的话,其他以它为数据域的类也会出现问题,结果就导致整个代码混乱。而现在这个题的写法比较紧凑,主类中的个个类数据域之间互不干扰,比较好发现问题并及时修改它。
在题目集04的7-3题中有关的知识点是继承。图形继承及编写程序,实现图形类的继承,并定义相应的类对象进行测试。继承是java在软件重用方面一个重要且功能强大的特征。假设要定义一个类,对圆,矩形和三角形建模,这些类有很多共同的特征。设计这些类来避免冗长并使系统易于理解和易于维护的最好方式就是使用继承。继承使得你在定义一个通用的类即父类,之后继承该类为一个更特定的类即子类。使用类对同一类型的对象进行建模,不同的类可能会有一些共同的特征或行为,可以在一些通用的类中表达这些共同之处,并被其他类所共享。所以Shape类、Circle类、Rectangle都是共享类。它们的子类可以从它的父类中继承可访问的数据域和方法,子类和它的父类形成了“是一种的关系”’,其中关键字extends告诉了编译器,这些类继承自哪个类。此外,按着题要求的输出, 应使用构造方法链。构造方法链可以调用重载的构造方法或父类的构造方法。且当构造一个子类的对象时,子类的构造方法会在完成自己的任务之前,首先调用它的父类的构造方法。书写的相关代码如下图所示:
Shape()
{System.out.println("Constructing Shape");}
{ System.out.println("Constructing Circle");}
Circle(){}
{System.out.println("Constructing Rectangle");}
Rectangle(){}
{System.out.println("Constructing Ball");}
Ball(){}
{System.out.println("Constructing Box");}
Box(){}
题目集6的7-5题的设计思路与上一题的类似,也使用到了继承,不过在本题中,它们的公共父类Shape类我省略了,改代码与上一个代码还是有所不同,主要体现在主函数里,在这里写了一个ArrayList类,ArrayList对象可以用于存储一个对象列表,ArrayList是一种泛型类,具有一个泛型类型E。创建一个ArrayList时,可以指定一个具体的类型来代替E。在创建ArrayLiat类之前,由于ArrayList位于java.util包中,所以必须在该代码的第一行导入该包:
import java.util.ArrayList;
之后在主函数里运用该泛型类,
ArrayList list=new ArrayList();
for(int i=0;i<number2;i++) { double length= input.nextDouble(); double width=input.nextDouble(); Rectangle rectangle = new Rectangle(length,width); if(rectangle.checkValid(length,width)==false) { System.out.println("Wrong Format"); System.exit(0); } else { list.add(rectangle.getArea()); n++; } }
在分析题目集6的7-6题时 请先看类
在这个类图中清晰的告诉了我们 GetArea类是另外两个不相关类的公共接口。从书中我们认识到接口是一种与类相似的结构,用于为对象定义公共的操作。接口在许多方面都与抽象类很相似,但它的目的是指明相关或者不相关类的对象的共同行为。在java中,接口被看作是一种特殊的类,且不能使用new操作符创建接口的实例。类与接口之间的关系称为接口继承,接口继承和类继承在本质上是相同的。interface关键字用于表示已个接口,使用implements关键字让对象所属的类实现这个接口。如下代码所示:
interface gettArea{ public abstract double getArea(); } class S implements gettArea{ private double radius; public boolean vai() { if(radius<=0) return false; else return true; } public double getRadius() { return radius; } public void setRadius(double radius) { this.radius = radius; } public S(double radius) { this.radius = radius; } @Override public double getArea() { // TODO 自动生成的方法存根 return Math.PI*radius*radius; } }
特别注意的是:接口没有定义为抽象类,但接口中含有抽象的方法,若某个类连接了这个接口但没有实现该接口中的抽象方法,则该类也将定义为抽象类。一个类可以实现多个接口,但是自能继承一个父类。接口可以继承其他接口但不能继承其他类,一个类可以继承它的父类同时实现多个接口。如果以个类实现了一个接口,那么这个接口就类似于该类的一个父类。可以将接口当做一种数据类型使用,将接口类型的变量转换为它的子类,反过来也可以。写代码时,通常使用接口类而非抽象类,因为接口可以为不相关类定义共同的父类型。接口比类比较灵活,因为不用使用所有东西都属于同一个类型的类。在设计程序的过程中,我们了解到抽象类和接口都是用来指定多个对象的共同特征,那么如何确定在什么情况下应该使用接口,什么情况下应该使用类呢?其实,一般来说,清晰描述父子关系的强的是“是.......的一种”关系应该用类建模。弱的“是.....的一种”关系也属于类属关系,可以用接口建模。
在题目集六中,主要是正则表达式的练习。在写有关正则表达式的代码题中,首先要了解到正则表达式的一些运用规则,从书和网络上可以查找到相关的资料。要注意的是,在需要运用正则表达式的代码中首先要先写如下形式的代码:
import java.util.regex.Matcher; import java.util.regex.Pattern;
题目继承会需要编写代码来验证用户的输入,比如验证输入是否是一个数字,是否是一个全部小写的字符串,或者社会安全号。如何编写这种类型的代码呢?一个简单而有效的做法是使用正则表达式来完成这个任务。在写有关正则表达式的相关代码时我认识到了正则表达式是一个强大的工它可以有效地处理字符串,可以使用正则表达式来匹配、替换和拆分字符串。在写简单的qq号校验代码中,就可以充分体现到正则表达式的优点:
import java.util.Scanner; 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); String sentence=input.nextLine(); boolean b=sentence.matches("[1-9][0-9]{4,14}"); if(b==true) System.out.println("你输入的QQ号验证成功"); else System.out.println("你输入的QQ号验证失败"); } }
我们输入:1234567890
在这里可以给出相应的输出:你输入的QQ号验证成功。输入:123456789O,则输出:你输入的QQ号验证失败。让我们从String类中的matches方法开始。咋一看,matches方法很类似于equals方法。然后通过写代码调试的过程中发现matches的方法功能更强大,它不仅可以匹配一个固定的字符串,还可以匹配一个模式的字符串。正则表达式是由字面符和特殊字符组成的,详细的还得参考网络。
原文:https://www.cnblogs.com/805a45646/p/14706750.html