第二次blog作业
前言:
这三次题目集相对来说难度比前面三次的难度更高,对java的理解等也需要大幅提高。这三次blog让我对java的三大特性有了更高的理解,对封装,继承,多态的理解与使用更上一层。但是还是在java学习过程中充满困难,对正则表达式的运用还不太熟练,以及java的各种语法还只刚刚了解。对java的理解自我感觉还是不太熟悉,总之学习java的过程是个艰难的过程,还需要继续努力。
踩坑心得:
这三次题目集进行了很多次提交,其中有的题目对我来说很难很难,尝试了很对次都没有成功,尤其是在正则表达式方面的编写方面有一些难以理解,简单些的正则表达式编写没问题,但是对于题目集中困难的正则表达式,在此编写上面感觉到了困难。其他题目主要就涉及了封装,继承,多态的利用。我浅谈一下我对封装,继承,多态的理解。
封装无非就是一个对象(类)中的部分属性或数据是私有,不能被外界访问,通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
所谓继承就是一个类获得另一个类的属性,方法,并且可以拓展从另一个类得来的方法,这样继承的类称为子类,被继承的被称为父类,以提高代码的利用率。
多态就是一个方法在不同的情况下有不同的行为和表现方式,多态通过接口和抽象来表现。
接口可以定义常量,不能定义变量,接口中所有的方法都是抽象方法,如果一个类继承了接口则此类必须实现该接口的所有抽象方法。
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现,抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。抽象类并不意味着其中的方法都是抽象方法。
下面看一个网上流传最广泛的例子:门和警报的例子:门都有open( )和close( )两个动作,此时我们可以定义通过抽象类和接口来定义这个抽象概念:
abstract class Door { public abstract void open(); public abstract void close(); }
或者
interface Door { public abstract void open(); public abstract void close(); }
但是现在如果我们需要门具有报警alarm( )的功能,那么该如何实现?下面提供两种思路:
1)将这三个功能都放在抽象类里面,但是这样一来所有继承于这个抽象类的子类都具备了报警功能,但是有的门并不一定具备报警功能;
2)将这三个功能都放在接口里面,需要用到报警功能的类就需要实现这个接口中的open( )和close( ),也许这个类根本就不具备open( )和close( )这两个功能,比如火灾报警器。
从这里可以看出, Door的open() 、close()和alarm()根本就属于两个不同范畴内的行为,open()和close()属于门本身固有的行为特性,而alarm()属于延伸的附加行为。因此最好的解决办法是单独将报警设计为一个接口,包含alarm()行为,Door设计为单独的一个抽象类,包含open和close两种行为。再设计一个报警门继承Door类和实现Alarm接口。
参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:
应用程序共测试三个功能:
- 求下n天
- 求前n天
- 求两个日期相差的天数
注意:严禁使用Java中提供的任何与日期相关的类与方法,并提交完整源码,包括主类及方法(已提供,不需修改).
7-2聚合代码如下:
import java.util.Scanner; class Year{ int value; public Year() { } public Year(int value) { this.value=value; } public int getValue() { return value; } public void setValue(int value) { this.value=value; } public boolean isLeapyear() { if((value%4==0&&value%100!=0)||value%400==0) { return true; } else { return false; } } public boolean validate() { if(value<1900||value>2050) { return false; } else { return true; } } public void yearIncrement() { value++; } public void yearReduction() { value--; } } class Month { int value; Year year; public Month() { } public Month(int yearValue,int monthValue) { this.year=new Year(yearValue); this.value=monthValue; } public int getValue() { return value; } public void setValue(int value) { this.value=value; } public Year getYear() { return year; } public void setYear(Year year) { this.year=year; } public void resetMin() { value=1; } public void resetMax() { value=12; } public boolean validate() { if(value<1||value>12) { return false; } else { return true; } } public void monthIncrement() { value++; } public void monthReduction() { value--; } } class Day { int value; Month month; int mon_maxnum[]={31,28,31,30,31,30,31,31,30,31,30,31}; //public Object getMonth; public Day() { } public Day(int yearValue,int monthValue,int dayValue) { this.month=new Month(yearValue,monthValue); this.value=dayValue; } public int getValue() { return value; } public void setValue(int value) { this.value=value; } public Month getMonth() { return month; } public void setMonth(Month value) { this.month=value; } public void resetMin() { value=1; } public void resetMax() { value=mon_maxnum[month.getValue()-1]; } public boolean validate() { if(this.getMonth().getYear().isLeapyear()) mon_maxnum[1]=29; if(value>=1&&value<=mon_maxnum[month.getValue()-1]) { return true; } else { return false; } } public void dayIncrement() { value++; } public void dayReduction() { value--; } } class DateUtil { Day day; public DateUtil() { } public DateUtil(int y,int m,int d) { this.day=new Day(y,m,d); } public Day getDay() { return day; } public void setDay(Day d) { this.day=d; } public boolean checkInputValidity() { if((this.getDay().getMonth().getYear().validate())&&(this.getDay().getMonth().validate())&&this.getDay().validate()) { return true; } else { return false; } } public boolean compareDates(DateUtil date) { if(date.getDay().getMonth().getYear().getValue()<this.getDay().getMonth().getYear().getValue()) { return false; } else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()<this.getDay().getMonth().getValue()) { return false; } else if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()&&date.getDay().getMonth().getValue()==this.getDay().getMonth().getValue()&&date.getDay().getValue()<this.getDay().getValue()) { return false; } else { return true; } } public boolean equalTwoDates(DateUtil date) { if(date.getDay().getMonth().getYear().getValue()==this.getDay().getMonth().getYear().getValue()) { if(date.getDay().getMonth().getValue()==this.getDay().getMonth().getValue()) { if(date.getDay().getValue()==this.getDay().getValue()) { return true; } } } return false; } public String showDate() { return this.getDay().getMonth().getYear().getValue()+"-"+this.getDay().getMonth().getValue()+"-"+this.getDay().getValue(); } public DateUtil getNextNdays(int n)//下n天 { int i=0,j=0,k=0; int a[]={31,28,31,30,31,30,31,31,30,31,30,31}; i=this.getDay().getMonth().getYear().getValue();//年 j=this.getDay().getMonth().getValue();//月 k=this.getDay().getValue();//日 if(this.getDay().getMonth().getYear().isLeapyear()) { a[1]=29; } for (int p= 0; p< n; p++) { k++; if (k>a[j-1]) { k = 1; j++; if (j> 12) { j= 1; i++; } } } return new DateUtil(i, j, k); } public DateUtil getPreviousNDays(int n)//前n天 { int i=0,j=0,k=0; int a[]={31,28,31,30,31,30,31,31,30,31,30,31}; i=this.getDay().getMonth().getYear().getValue();//年 j=this.getDay().getMonth().getValue();//月 k=this.getDay().getValue();//日 if(this.getDay().getMonth().getYear().isLeapyear()) { a[1]=29; } for (int p= 0; p< n; p++) { k--; while (k< 1) { j--; if (j < 1) { j= 12; i--; } k+= a[j-1]; } } return new DateUtil(i,j,k); } public int getDaysofDates(DateUtil date)//两个日期间相差天数 { DateUtil b1=this;//小 DateUtil b2=date;//大 if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } if(this.equalTwoDates(date)) { return 0; } else if(!this.compareDates(date)) { b1=date; b2=this; } int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int i,j,ts=0; for(i=b1.getDay().getMonth().getYear().getValue()+1;i<b2.getDay().getMonth().getYear().getValue();i++){//两个日期的年数之和 ts=ts+365; if(new Year(i).isLeapyear()) ts++; } if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()==b2.getDay().getMonth().getValue()){//年份相同,月份相同,日不同 ts=b2.getDay().getValue()-b1.getDay().getValue(); } else if(b1.getDay().getMonth().getYear().getValue()==b2.getDay().getMonth().getYear().getValue()&&b1.getDay().getMonth().getValue()!=b2.getDay().getMonth().getValue()){//年份相同,月份不同 if(b1.getDay().getMonth().getYear().isLeapyear())//是闰年 a[2]=29; ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期该月剩余的天数 ts=ts+b2.getDay().getValue();//大日期的天数 for(j=b1.getDay().getMonth().getValue()+1;j<=b2.getDay().getMonth().getValue()-1;j++)//月份天数和 ts+=a[j]; } else if(b1.getDay().getMonth().getYear().getValue()!=b2.getDay().getMonth().getYear().getValue()){//年份不同 ts=ts+a[b1.getDay().getMonth().getValue()]-b1.getDay().getValue();//小日期在该月剩余的天数 ts=ts+b2.getDay().getValue();//大日期在该月已经过的天数 for(j=b1.getDay().getMonth().getValue()+1;j<=12;j++)//小日期在该年剩余的天数 ts=ts+a[j]; for(j=b2.getDay().getMonth().getValue()-1;j>0;j--)//大日期在该年已经过的天数 ts=ts+a[j]; if(b1.getDay().getMonth().getYear().isLeapyear()&&b1.getDay().getMonth().getValue()<=2)//如果小日期该年为闰年且该天在1月或2月 ts++; if(b2.getDay().getMonth().getYear().isLeapyear()&&b2.getDay().getMonth().getValue()>2)//如果大日期该年为闰年且该天在1月或2月后 ts++; } return ts; } } public class Main { public static void main(String[] args) { Scanner input=new Scanner(System.in); int a=input.nextInt(); int year=input.nextInt(); int month=input.nextInt(); int day=input.nextInt(); DateUtil c=new DateUtil(year,month,day); switch(a) { case 1: int b=input.nextInt(); if(!c.checkInputValidity()||b<0) { System.out.println("Wrong Format"); System.exit(0); } System.out.println(c.getNextNdays(b).showDate()); break; case 2: int m=input.nextInt(); if(!c.checkInputValidity()||m<0) { System.out.println("Wrong Format"); System.exit(0); } System.out.println(c.getPreviousNDays(m).showDate()); break; case 3: int year1=input.nextInt(); int month1=input.nextInt(); int day1=input.nextInt(); DateUtil c2=new DateUtil(year1,month1,day1); if(!c.checkInputValidity()||!c2.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } System.out.println(c.getDaysofDates(c2)); break; default: System.out.println("Wrong Format"); } } }
7-4聚合二代码如下:
import java.util.Scanner; class Year{ int value; public Year() { } public Year(int value) { this.value=value; } public int getValue() { return value; } public void setValue(int value) { this.value=value; } public boolean isLeapyear() { if((value%4==0&&value%100!=0)||value%400==0) { return true; } else { return false; } } public boolean validate() { if(value<1820||value>2020) { return false; } else { return true; } } public void yearIncrement() { value++; } public void yearReduction() { value--; } } class Month { int value; public Month() { } public Month(int value) { this.value=value; } public int getValue() { return value; } public void setValue(int value) { this.value=value; } public void resetMin() { value=1; } public void resetMax() { value=12; } public boolean validate() { if(value<1||value>12) { return false; } else { return true; } } public void monthIncrement() { value++; } public void monthReduction() { value--; } } class Day { int value; //Month month; //int mon_maxnum[]={31,28,31,30,31,30,31,31,30,31,30,31}; //public Object getMonth; public Day() { } public Day(int value) { this.value=value; } public int getValue() { return value; } public void setValue(int value) { this.value=value; } public void dayIncrement() { value++; } public void dayReduction() { value--; } } class DateUtil { Year year; Month month; Day day; int mon_maxnum[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; public DateUtil() { } public DateUtil(int year,int month,int day) { this.year=new Year(year); this.month=new Month(month); this.day=new Day(day); } public Year getYear() { return year; } public void setYear(Year year) { this.year=year; } public Day getDay() { return day; } public void setDay(Day day) { this.day=day; } public Month getMonth() { return month; } public void setMonth(Month m) { this.month=m; } public void setDaymin() { this.day.value=1; } public void setDaymax() { if(this.year.isLeapyear()) { mon_maxnum[2]=29; } this.day.value= mon_maxnum[this.month.value-1]; } public boolean checkInputValidity() { if(this.year.isLeapyear()) mon_maxnum[2]=29; if(this.year.validate()&&this.month.validate()&&this.day.value>=1&&this.day.value<=mon_maxnum[this.month.value]) { return true; } else { return false; } } public boolean compareDates(DateUtil date) { if(date.year.getValue()<this.year.getValue()) { return false; } else if(date.year.getValue()==this.year.getValue()&&date.month.getValue()<this.month.getValue()) { return false; } else if(date.year.getValue()==this.year.getValue()&&date.month.getValue()==this.month.getValue()&&date.getDay().getValue()<this.getDay().getValue()) { return false; } else { return true; } } public boolean equalTwoDates(DateUtil date) { if(date.year.getValue()==this.year.getValue()) { if(date.month.getValue()==this.month.getValue()) { if(date.getDay().getValue()==this.getDay().getValue()) { return true; } } } return false; } public String showDate() { return this.year.getValue()+"-"+this.month.getValue()+"-"+this.getDay().getValue(); } private final int[] a = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; private int getDayOfMonth(int year, int month) { int days =a[month - 1]; if (month == 2 && isLeapYear(year)) { days = 29; } return days; } public boolean isLeapYear(int year)//判断year是否为闰年 { return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0; } public DateUtil getNextNdays(int n)//下n天 { //int i=0,j=0,k=0; //int i=this.getYear().value;//年 //int j=this.getMonth().value;//月 //int k=this.getDay().value;//日 int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int year = this.year.value; int month = this.month.value; int day = this.day.value; for (int p= 0; p< n; p++) { day++; if (day>getDayOfMonth(year, month)) { day = 1; month++; if (month> 12) { month= 1; year++; } } } return new DateUtil(year, month, day); } public DateUtil getPreviousNDays(int n)//前n天 { int i=0,j=0,k=0; int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; i=this.year.value;//年 j=this.month.value;//月 k=this.getDay().value;//日 for (int p= 0; p< n; p++) { k--; while (k< 1) { j--; if (j < 1) { j= 12; i--; } k+= getDayOfMonth(i, j); } } return new DateUtil(i,j,k); } public int getDaysofDates(DateUtil date)//两个日期间相差天数 { DateUtil b1=this;//小 DateUtil b2=date;//大 if (!date.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } if(this.equalTwoDates(date)) { return 0; } else if(!this.compareDates(date)) { b1=date; b2=this; } int a[]={0,31,28,31,30,31,30,31,31,30,31,30,31}; int i,j,ts=0; for(i=b1.year.getValue()+1;i<b2.year.getValue();i++){//两个日期的年数之和 ts=ts+365; if(new Year(i).isLeapyear()) ts++; } if(b1.year.getValue()==b2.year.getValue()&&b1.month.getValue()==b2.month.getValue()){//年份相同,月份相同,日不同 ts=b2.getDay().getValue()-b1.getDay().getValue(); } else if(b1.year.getValue()==b2.year.getValue()&&b1.month.getValue()!=b2.month.getValue()){//年份相同,月份不同 if(b1.year.isLeapyear())//是闰年 a[2]=29; ts=ts+a[b1.month.getValue()]-b1.getDay().getValue();//小日期该月剩余的天数 ts=ts+b2.getDay().getValue();//大日期的天数 for(j=b1.month.getValue()+1;j<=b2.month.getValue()-1;j++)//月份天数和 ts+=a[j]; } else if(b1.year.getValue()!=b2.year.getValue()){//年份不同 ts=ts+a[b1.month.getValue()]-b1.getDay().getValue();//小日期在该月剩余的天数 ts=ts+b2.getDay().getValue();//大日期在该月已经过的天数 for(j=b1.month.getValue()+1;j<=12;j++)//小日期在该年剩余的天数 ts=ts+a[j]; for(j=b2.month.getValue()-1;j>0;j--)//大日期在该年已经过的天数 ts=ts+a[j]; if(b1.year.isLeapyear()&&b1.month.getValue()<=2)//如果小日期该年为闰年且该天在1月或2月 ts++; if(b2.year.isLeapyear()&&b2.month.getValue()>2)//如果大日期该年为闰年且该天在1月或2月后 ts++; } return ts; } } public class Main { public static void main(String[] args) { Scanner input=new Scanner(System.in); int a=input.nextInt(); int year=input.nextInt(); int month=input.nextInt(); int day=input.nextInt(); DateUtil c=new DateUtil(year,month,day); switch(a) { case 1: int b=input.nextInt(); if(!c.checkInputValidity()||b<0) { System.out.println("Wrong Format"); System.exit(0); } System.out.println(c.showDate()+" "+"next"+" "+b+" "+"days is:"+c.getNextNdays(b).showDate()); break; case 2: int m=input.nextInt(); if(!c.checkInputValidity()||m<0) { System.out.println("Wrong Format"); System.exit(0); } System.out.println(c.showDate()+" "+"previous"+" "+m+" "+"days is:"+c.getPreviousNDays(m).showDate()); break; case 3: int year1=input.nextInt(); int month1=input.nextInt(); int day1=input.nextInt(); DateUtil c2=new DateUtil(year1,month1,day1); if(!c.checkInputValidity()||!c2.checkInputValidity()) { System.out.println("Wrong Format"); System.exit(0); } System.out.println("The days between"+" "+c.showDate()+" "+"and"+" "+c2.showDate()+" "+"are:"+c.getDaysofDates(c2)); break; default: System.out.println("Wrong Format"); } } }
分析:
对于 第一种聚合来看,从类图当中就能看见各类里面的属性方法的结构清晰,类里使用的方法较少,更容易让人理清。但同时它的缺点也很明显,无法直接调用每一个类,想要调用一个类需要先调用上一个类,编写代码更加复杂,多了很多不必要的麻烦。
对于第二种聚合来看,虽然在功能类中多了很多方法,但是他可以直接对月日年进行引用,更加方便,从圈复杂度来看聚合二中的复杂度要更低一些,说明聚合二的效率要更高。
就我本人来说更喜欢聚合二中的结构,编写起来简单明了,不用重复各种调用。下面来看俩者的类图,圈复杂度等等:
聚合一:

聚合二:


编写程序,实现图形类的继承,并定义相应类对象并进行测试。
- 类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; class Shape { public double getArea() { return 0.0; } public Shape() { System.out.println("Constructing Shape"); } } class Circle extends Shape { private double radius; public Circle() { System.out.println("Constructing Circle"); } public void setRadius(double radius) { this.radius=radius; } public double getRadius() { return radius; } public double getArea() { return Math.PI*radius*radius; } } class Rectangle extends Shape { public Rectangle() { System.out.println("Constructing Rectangle"); } private double width; private double 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 width*length; } } class Ball extends Circle { public Ball() { System.out.println("Constructing Ball"); } public double getArea() { double r1=getRadius(); return 4.0*Math.PI*r1*r1; } public double getVolume() { double r1=getRadius(); return (4.0/3.0)*Math.PI*r1*r1*r1; } } class Box extends Rectangle { private double height; public Box() { System.out.println("Constructing Box"); } public double getHeight() { return height; } public void setHeight(double height) { this.height=height; } public double getArea() { double chang=getLength(); double kuan=getWidth(); return (2*chang*kuan)+(2*chang*height)+(2*kuan*height); } public double getVolume() { double chang=getLength(); double kuan=getWidth(); return chang*kuan*height; } } public class Main { public static void main(String[] args) { Scanner input=new Scanner(System.in); int choice=input.nextInt(); switch(choice) { case 1: double radius=input.nextDouble(); if(radius<0.0) { System.out.println("Wrong Format"); } else { Circle circle=new Circle(); circle.setRadius(radius); System.out.println(String.format("Circle's area:%.2f",circle.getArea())); } break; case 2: double width=input.nextDouble(); double length=input.nextDouble(); if(width<0.0||length<0.0) { System.out.println("Wrong Format"); } else { Rectangle rectangle=new Rectangle(); rectangle.setWidth(width); rectangle.setLength(length); System.out.println(String.format("Rectangle's area:%.2f",rectangle.getArea())); } break; case 3: double r1=input.nextDouble(); if(r1<0.0) { System.out.println("Wrong Format"); } else { Ball ball=new Ball(); ball.setRadius(r1); System.out.println(String.format("Ball's surface area:%.2f",ball.getArea())); System.out.println(String.format("Ball's volume:%.2f",ball.getVolume())); } break; case 4: double kuan=input.nextDouble(); double chang=input.nextDouble(); double gao=input.nextDouble(); if(kuan<0.0||chang<0.0||gao<0.0) { System.out.println("Wrong Format"); } else { Box box=new Box(); box.setWidth(kuan); box.setLength(chang); box.setHeight(gao); System.out.println(String.format("Box's surface area:%.2f",box.getArea())); System.out.println(String.format("Box's volume:%.2f",box.getVolume())); } break; default: System.out.println("Wrong Format"); } } }
掌握类的继承、多态性及其使用方法。具体需求参见作业指导书。
输入格式:
从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。
输出格式:
- 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出
Wrong Format。 - 如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
- 各个图形的面积;
- 所有图形的面积总和;
- 排序后的各个图形面积;
- 再次所有图形的面积总和。
代码如下:
import java.util.Scanner; import java.util.ArrayList; import java.util.Arrays; public class Main{ public static void main(String[] args) { Scanner input=new Scanner(System.in); ArrayList<Shape> list=new ArrayList<>(); int a=input.nextInt(); int b=input.nextInt(); int c=input.nextInt(); double sum=0; int t=0; if(a<0||b<0||c<0) { System.out.println("Wrong Format"); System.exit(0); } for(int i=0;i<a;i++) { double radius=input.nextDouble(); list.add(new Circle(radius)); if(list.get(i).validate()==false) { t=1; } } for(int i=0;i<b;i++) { double width=input.nextDouble(); double length=input.nextDouble(); list.add(new Rectangle(width,length)); if(list.get(i).validate()==false) { t=1; } } for(int i=0;i<c;i++) { double side1=input.nextDouble(); double side2=input.nextDouble(); double side3=input.nextDouble(); list.add(new Triangle(side1,side2,side3)); if(list.get(i).validate()==false) { t=1; } } for(int i=0;i<a+b+c;i++) { if(list.get(i).validate()==false) { t=1; } } if(t==0&&(a>=0&&b>=0&&c>=0)) { System.out.println("Original area:"); for(int i=0;i<a+b+c;i++) { System.out.print(String.format("%.2f",list.get(i).getArea())+" "); sum=sum+list.get(i).getArea(); } System.out.println(String.format("\nSum of area:%.2f",sum)); sort(list); System.out.println("Sorted area:"); for(int i=0;i<a+b+c;i++) { System.out.print(String.format("%.2f",list.get(i).getArea())+" "); } System.out.println(String.format("\nSum of area:%.2f",sum)); } else { System.out.println("Wrong Format"); } } public static ArrayList<Shape> sort(ArrayList<Shape> list) { int num; Shape temp; for(int i=0;i<list.size();i++) { num=i; while(num!=0&&list.get(num).getArea()<list.get(num-1).getArea()) { temp=list.get(num); list.set(num,list.get(num-1)); list.set(num-1,temp); num--; } } return list; } } abstract class Shape { public abstract double getArea(); public abstract boolean validate(); } class Circle extends Shape { double radius; public Circle(double radius) { this.radius=radius; } public double getArea() { return Math.PI*radius*radius; } public boolean validate() { if(radius<=0) { return false; } else { return true; } } } class Rectangle extends Shape { double width; double length; public Rectangle(double width,double length) { this.width=width; this.length=length; } public double getArea() { return width*length; } public boolean validate() { if(width<=0||length<=0) { return false; } else { return true; } } } class Triangle extends Shape { double side1,side2,side3; public Triangle(double side1,double side2,double side3) { this.side1=side1; this.side2=side2; this.side3=side3; } public double getArea() { double p=(side1+side2+side3)/2; return Math.sqrt(p*(p-side1)*(p-side2)*(p-side3)); } public boolean validate() { if(side1+side2<=side3||side1+side3<=side2||side2+side3<=side1) { return false; } if(side1-side2>=side3||side1-side3>=side2||side2-side3>=side1) { return false; } return true; } }
编写程序,使用接口及类实现多态性,类图结构如下所示:
代码如下:
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner input=new Scanner(System.in); double radius=input.nextDouble(); double width=input.nextDouble(); double length=input.nextDouble(); if(radius<=0||width<=0||length<=0) { System.out.print("Wrong Format"); System.exit(0); } Circle circle=new Circle(radius); Rectangle rectangle=new Rectangle(width,length); System.out.println(String.format("%.2f",circle.getArea())); System.out.print(String.format("%.2f",rectangle.getArea())); } } interface GetArea { public abstract double getArea(); } class Circle implements GetArea { double radius; public double getRadius() { return radius; } public void setRadius(double radius) { this.radius=radius; } public Circle(double radius) { this.radius=radius; } public Circle() { } public double getArea() { return Math.PI*radius*radius; } } class Rectangle implements GetArea { double width; double 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 Rectangle(double width,double length) { this.width=width; this.length=length; } public Rectangle() { } public double getArea() { return width*length; } }
上述三道题设计到了java中封装,继承,多态,接口,抽象的运用。
封装无非就是一个对象(类)中的部分属性或数据是私有,不能被外界访问,通过这种方式,对象对内部数据提供了不同级别的保护,以防止程序中无关的部分意外的改变或错误的使用了对象的私有部分。
所谓继承就是一个类获得另一个类的属性,方法,并且可以拓展从另一个类得来的方法,这样继承的类称为子类,被继承的被称为父类,以提高代码的利用率。
多态就是一个方法在不同的情况下有不同的行为和表现方式,多态通过接口和抽象来表现。
接口可以定义常量,不能定义变量,接口中所有的方法都是抽象方法,如果一个类继承了接口则此类必须实现该接口的所有抽象方法。
抽象方法是一种特殊的方法:它只有声明,而没有具体的实现,抽象方法必须用abstract关键字进行修饰。如果一个类含有抽象方法,则称这个类为抽象类,抽象类必须在类前用abstract关键字修饰。抽象类
并不意味着其中的方法都是抽象方法。
它们各自的圈复杂度等如下:






几个正则表达式的题目:
水文检验,这道字符匹配题难度比较高
使用Java中的字符串处理类以及正则表达式对输入字符串数据进行合法性校验及计算。(具体需求参见附件 2021-OO第04次作业-1指导书V1.0.pdf )
输入格式:
假定分水口门的数据上报时是采用人工输入的方式,每一行代表一个整点时刻的分水数据,各数据之间采用“|”符号进行分隔,每次可以输入多条数据,直到遇到用户输入“exit”为止,每一行输入数据共包含五部分:测量时间、目标水位、实际水位、开度(包含目标开度和实际开度,以“/”分隔)、流量。 各数据格式要求如下:
- 测量时间:格式为“年/月/日 时:分”,其中年份取值范围为[1,9999],“月”与“日”为一位数时之前不加“0”,日期与时间之间有一个空格,“时”与“分”之间采用冒号分隔(英文半角),“时”为一位数时之前不加“0”,“分”始终保持两位,且始终为“00”。注意:“时”数必须是24小时进制中的偶数值。
- 目标水位、实际水位、流量:均为实型数,取值范围为[1,1000), 小数点后保留1-3位小数或无小数(也无小数点)
- 目标开度、实际开度:实型数,取值范围为[1,10),必须保留2位小数,两个开度之间用“/”分隔
这道题需要对每个输入的数据进行测试,需要利用正则表达式来匹配输入的数据是否正确。难度很大。我感觉自己还是不太会
其他几道正则表达式的题目,相对来说较为基础,对照正则表达式的表格,对输入的数据进行一个一个的匹配就好了,就不多做分析了。正则表达式的关键就在于能记住各种字符的转换,能更好的运用。正则表达式难起来确实很难
简单的运用起来确实很简单。
构造正则表达式的方法和创建数学表达式的方法一样。也就是用多种元字符与运算符可以将小的表达式结合在一起来创建更大的表达式。正则表达式的组件可以是单个的字符、字符集合、字符范围、字符间的选择或者所有这些组件的任意组合。
正则表达式是由普通字符(例如字符 a 到 z)以及特殊字符(称为"元字符")组成的文字模式。模式描述在搜索文本时要匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。
所需要学习的正则表达式还有很多,还需要多加学习。
编写程序统计一个输入的Java源码中关键字(区分大小写)出现的次数。说明如下:
- Java中共有53个关键字(自行百度)
- 从键盘输入一段源码,统计这段源码中出现的关键字的数量
- 注释中出现的关键字不用统计
- 字符串中出现的关键字不用统计
- 统计出的关键字及数量按照关键字升序进行排序输出
- 未输入源码则认为输入非法
该题涉及到了java中集合框架的运用,做起来难度较大。此题主要采用map接口来实现java的集合类操作。
Map接口在Collection的基础上,为其中的每个对象指定了一个key,并使用Entry保存每个key-value对,以实现通过key快速定位到对象(value)。Map接口的主要方法包括:
size() - 集合内的对象数量
put(K,V)/putAll(Map) - 向Map内添加单个/批量对象
get(K) - 返回Key对应的对象
remove(K) - 删除Key对应的对象
keySet() - 返回包含Map中所有key的Set
values() - 返回包含Map中所有value的Collection
Map将key和value封装至一个叫做Entry的对象中,Map中存储的元素实际是Entry。只有在keySet()和values()方法被调用时,Map才会将keySet和values对象实例化。
每一个Map根据其自身特点,都有不同的Entry实现,以对应Map的内部类形式出现。
总结:
这几次题目集让我的java的水平有了提升,也让我对java的理解也提升了许多。学习java这几个月来,初步了解了java的核心是面向对象,知道面向对象跟面向过程的区别,了解了面向对象的思想学习java,
运用java起来就会更加方便,对题目的需求以及设计也会更便携。再其次就是了解了,java的基本三大特性,懂得了什么是封装,继承,多态。对其概念以及运用已经有了比较大的提升,在java的学习过程
中能够完全了解和掌握这三大特性,往往能起到很大的帮助。再就是对对抽象和接口也有了一定的认识,知道java学习过程中运用抽象或接口会对java的代码的编写以及理解会提供很大的便携。java学习的
过程是个任重而道远的过程,还需要不断的钻研与提升,还需要继续努力。老师的组织形式,作业安排,组织形式等等都很不错。

浙公网安备 33010602011771号