blog作业2

       目    录

一、前言

二、设计与分析

三、踩坑心得

四、改进建议

五、总结

一、前言

 

       题目集四题量较小,一共只有三题,但难度偏大,尤其是第一题题目要求过于复杂,我是看到都不想动手,这题考察了对正则表达式的使用能力,第二题主要考察对日期类聚合的使用能力,第三题主要考察对子类与父类之间的继承关系的理解以及类的封装性和方法重写;题目集二题量适中,难度也适中,第四题略难,主要原因还是对正则表达式的使用不熟悉,这一题我就输出了个wrong format骗了两分,结果被查重百分之百......前三题都是考察数组方法的使用,第五题主要考察对日期类聚合的设计能力,是题目集4第二题的升级版本;题目集六是三个题目集中题量最大的,但也是难度最小的,这个题目集做的比较舒服,第1、3、4题都是正则表达式的训练,分别利用正则表达式对QQ号、验证码、学号进行了校检,粗略自学一下正则表达式就可做出,第二题是字符串训练,第五题要求掌握类的继承、多态性及其使用方法,第六题要求使用接口及类实现多态性。

二、设计与分析

①题目集4(7-2)、题目集5(7-4)两种日期类聚合设计的优劣比较

7-2 日期问题面向对象设计(聚合一) (35 分)
 

参考题目7-2的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1900,2050] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

 

package demo;
import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);       
        int i = input.nextInt();
        if (i == 1) {                    //     计算后几天
            
            int year = input.nextInt();
            int month = input.nextInt();
            int day=input.nextInt();
            DateUtil date = new DateUtil(year, month, day);  //创建DateUtil类型对象date
           
            if (year<1900||year>2050||month<1||month>12||day<1||day>31) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            int after = input.nextInt();
            if (after < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            else {           
            System.out.println(date.getNextNDays(after).getYear()+"-"+date.getNextNDays(after).getMonth()+"-"+date.getNextNDays(after).getDay());
            }
        } else if (i == 2) {                           // 计算前几天            
            int year = input.nextInt();
            int month = input.nextInt();
            int day=input.nextInt();
            DateUtil datee = new DateUtil(year, month, day);                        //创建DateUtil类型对象datee
            if (year<1900||year>2050||month<1||month>12||day<1||day>31) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            int previous = input.nextInt();
            if (previous < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }            
            System.out.println(datee.getPreviousDays(previous).getYear()+"-"+datee.getPreviousDays(previous).getMonth()+"-"+datee.getPreviousDays(previous).getDay());
        }
            else if (i == 3) {    //test getDaysofDates method
            int year = input.nextInt();
            int month = input.nextInt();
            int day=input.nextInt();
            int yearr = input.nextInt();
            int monthh = input.nextInt();
            int dayy=input.nextInt();
            DateUtil Date1 = new DateUtil(year, month, day);       //创建DateUtil类型对象Date1
            DateUtil Date2 = new DateUtil(yearr, monthh, dayy);      //创建DateUtil类型对象Date2
            if (year>=1900||year<=2050||month>=1||month<=12||day>=1||day<=31||yearr>=1900||yearr<=2050||monthh>=1||monthh<=12||dayy>=1||dayy<=31) {
               System.out.println( Date1.getDaysofDates(Date2));
            } 
            else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        }
        else{
            System.out.println("Wrong Format");
            System.exit(0);
        }
    }
}         

class DateUtil {
    private int year;
    private int month;
    private int day;

    public DateUtil(int year, int month, int day) {          
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public void setYear(int year) {
        this.year = year;
    }
    public int getYear() {
        return year;
    }
    public void setMonth(int month) {
        this.month = month;
    }
    public int getMonth() {
        return month;
    }
    public void setDay(int day) {
        this.day = day;
    }
    public int getDay() {
        return day;
    }

    private  int[] n = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    private int getDayOfMonth(int year, int month) {       //每个月份对应的天数
        int days = n[month - 1];
        boolean b1=isLeapYear(getYear());
        if (month == 2 && b1==true) {              //二月闰年
            days = 29;
        }
        return days;
    }

   
    public boolean isLeapYear(int year)                //判断year是否为闰年
    {
        if( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            return true;
        }
        else {
            return false;
        }
    }


    public DateUtil getNextNDays(int n)//取得year-month-day的下n天日期
    {
        int year = this.year;
        int month = this.month;
        int day = this.day;

        for (int i = 0; i < n; i++) {
            day++;
            if (day > getDayOfMonth(year, month)) {         //当前日期到达当前月份的最后一天
                day = 1;
                month++;
                if (month > 12) {              //跨年
                    month = 1;
                    year++;
                }
            }
        }
        return new DateUtil(year, month, day);
    }

   public DateUtil getPreviousDays(int n)//取得year-month-day的前n天日期
    {
        int year = this.year;
        int month = this.month;
        int day = this.day;
        for (int i = 0; i < n; i++) {
            day--;
            while (day < 1) {
                month--;
                if (month < 1) {
                    month = 12;
                    year--;
                }
                day = day+getDayOfMonth(year, month);
            }
        }
        return new DateUtil(year, month, day);
    }

       public boolean compareDates(DateUtil date)//比较当前日期与date的大小(先后)
    {
        if (this.year > date.year) {
            return true;
        }
        if (this.year == date.year) {
            if (this.month > date.month) {
                return true;           
            }
            if (this.month == date.month) {
                if (this.day >= date.day) {
                    return true;
                }
            }
        }
        else 
        return false;
        return false;
    
    }

    public boolean same(DateUtil date)//判断两个日期是否相等
    {
        if (date != null) {
            if (year == date.year && month == date.month && day == date.day) {
                return true;
            }
        }
        else {
        return false;
    }
        return false;
    }
    private static  int[] fuck = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
    public int getDaysofDates(DateUtil date)//求当前日期与date之间相差的天数
    {
        DateUtil dateUtil1 = this; // 小
        DateUtil dateUtil2 = date ; // 大
        boolean b2=compareDates(date);
        if (b2==true) {
            dateUtil1 = date;         //error
            dateUtil2 = this;
        }

        int days;
        int leapYearnum = 0;
        for (int i = dateUtil1.getYear(); i < dateUtil2.getYear(); i++) {
            if (isLeapYear(i)) {
                leapYearnum++;
            }
        }

        days = 365 * (dateUtil2.getYear() - dateUtil1.getYear()) + leapYearnum;

        int d1 = fuck[dateUtil1.getMonth() - 1] + dateUtil1.getDay() + (dateUtil1.getMonth() > 2 && isLeapYear(dateUtil1.getYear()) ? 1 : 0);
        int d2 = fuck[dateUtil2.getMonth() - 1] + dateUtil2.getDay() + (dateUtil2.getMonth() > 2 && isLeapYear(dateUtil2.getYear()) ? 1 : 0);
        return days - d1 + d2;
    }
    
    


}

 

 

 

 这题我主要思路就是一共就定义两个类,一个是包含主方法的主类,主方法中输入1、2、3供用户选择功能,然后再定义一个DateUtil类,里面储存数据和实现功能的方法

,在主类中创建dateutil类的对象并调用里面的方法实现各项功能,这么做当然是不太好的,主要是我认为这么做比较快,最好还是使用聚合的技术;
7-5 日期问题面向对象设计(聚合二) (40 分)
 

参考题目7-3的要求,设计如下几个类:DateUtil、Year、Month、Day,其中年、月、日的取值范围依然为:year∈[1820,2020] ,month∈[1,12] ,day∈[1,31] , 设计类图如下:

 

 

package demo;
import java.util.Scanner;

public class Test {
    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        
            int i = input.nextInt();
            if (i == 2) { // test getPreviousNDays method
            int previous = 0;
            int year = input.nextInt();
            int month = Integer.parseInt(input.next());
            int day=input.nextInt();

            DateUtil datee = new DateUtil(year, month, day);

            if (year<1820||year>2020||month<1||month>12||day<1||day>31) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

            previous = input.nextInt();

            if (previous < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            else {
                System.out.print(
                        datee.getYear() + "-" + datee.getMonth() + "-" + datee.getDay() + " previous " + previous + " days is:");
                System.out.println(datee.getPreviousNDays(previous).getYear()+"-"+datee.getPreviousNDays(previous).getMonth()+"-"+datee.getPreviousNDays(previous).getDay());
            }
            }
             
    
            else if (i == 1) { // test getNextNDays method
            int after = 0;
            int year = input.nextInt();
            int month = Integer.parseInt(input.next());
            int day=input.nextInt();

            DateUtil date = new DateUtil(year, month, day);

            if (year<1820||year>2020||month<1||month>12||day<1||day>31) {
                System.out.println("Wrong Format");
                System.exit(0);
            }

             after = input.nextInt();

            if (after < 0) {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            else {            
                System.out.print(date.getYear() + "-" + date.getMonth() + "-" + date.getDay() + " next " + after + " days is:");
            System.out.println(date.getNextNDays(after).getYear()+"-"+date.getNextNDays(after).getMonth()+"-"+date.getNextNDays(after).getDay());
            }
            }
            else if (i == 3) {    //test getDaysofDates method
            int year = input.nextInt();
            int month = Integer.parseInt(input.next());
            int day=input.nextInt();
            int yearr = input.nextInt();
            int monthh = Integer.parseInt(input.next());
            int dayy=input.nextInt();
            DateUtil Date1 = new DateUtil(year, month, day);       //创建DateUtil类型对象Date1
            DateUtil Date2 = new DateUtil(yearr, monthh, dayy);      //创建DateUtil类型对象Date2

            if (year>=1820||year<=2020||month>=1||month<=12||day>=1||day<=31||yearr>=1820||yearr<=2020||monthh>=1||monthh<=12||dayy>=1||dayy<=31) {
                
                System.out.println("The days between " + Date1.showDate() +
                                        " and " + Date2.showDate() + " are:"
                                        + Date1.getDaysofDates(Date2));
                            } 
             else {
                System.out.println("Wrong Format");
                System.exit(0);
            }
        }
        else{
            System.out.println("Wrong Format");
            System.exit(0);
        }
        
    }
}

class DateUtil {
    private int year;
    private int month;
    private int day;

    public DateUtil(int year, int month, int day) {
        this.year = year;
        this.month = month;
        this.day = day;
    }
    public void setYear(int year) {
        this.year = year;
    }
    public int getYear() {
        return year;
    }
   
   
    public void setMonth(int month) {
        this.month = month;
    }
    public int getMonth() {
        return month;
    }

   
    public void setDay(int day) {
        this.day = day;
    }
    public int getDay() {
        return day;
    }
   

    private final int[] array = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

    private int getDayOfMonth(int year, int month) {              //每月对应的天数
        int days = array[month - 1];
        if (month == 2 && isLeapYear(year)) {
            days = 29;
        }
        return days;
    }

   
    public boolean isLeapYear(int year)                //判断year是否为闰年
    {
        if( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) {
            return true;
        }
        else {
            return false;
        }
    }


    public DateUtil getNextNDays(long after)//取得year-month-day的下n天日期
    {
        int year = this.year;
        int month = this.month;
        int day = this.day;

        for (int i = 0; i < after; i++) {
            day++;
            if (day > getDayOfMonth(year, month)) {
                day = 1;
                month++;
                if (month > 12) {
                    month = 1;
                    year++;
                }
            }
        }
        return new DateUtil(year, month, day);
    }

    public DateUtil getPreviousNDays(long previous)//取得year-month-day的前n天日期
    {
        int year = this.year;
        int month = this.month;
        int day = this.day;
        for (int i = 0; i < previous; i++) {
            day--;
            while (day < 1) {
                month--;
                if (month < 1) {
                    month = 12;
                    year--;
                }
                day += getDayOfMonth(year, month);
            }
        }
        return new DateUtil(year, month, day);
    }

    public boolean compareDates(DateUtil date)//比较当前日期与date的大小(先后)
    {
        if (this.year > date.year) 
            return true;
        if (this.year == date.year) {
            if (this.month > date.month) 
                return true;
            if (this.month == date.month) {
                if (this.day >= date.day) 
                    return true;
            }
        }
        return false;
    }

    
    
    private static final int[] fuck = {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
    public int getDaysofDates(DateUtil date)//求当前日期与date之间相差的天数
    {
        DateUtil dateUtil1 = this; // 小
        DateUtil dateUtil2 = date; // 大
        if (this.compareDates(date)==true) {
            dateUtil1 = date;
            dateUtil2 = this;
        }

        int days;
        int leapYearNum = 0;
        for (int i = dateUtil1.getYear(); i < dateUtil2.getYear(); i++) {
            if (isLeapYear(i)) {
                leapYearNum++;
            }
        }

        days = 365 * (dateUtil2.getYear() - dateUtil1.getYear()) + leapYearNum;

        int d1 = fuck[dateUtil1.getMonth() - 1] + dateUtil1.getDay() + (dateUtil1.getMonth() > 2 && isLeapYear(dateUtil1.getYear()) ? 1 : 0);
        int d2 = fuck[dateUtil2.getMonth() - 1] + dateUtil2.getDay() + (dateUtil2.getMonth() > 2 && isLeapYear(dateUtil2.getYear()) ? 1 : 0);
        return days - d1 + d2;
    }
    
    public String showDate()//以“year-month-day”格式返回日期值
    {
        return year + "-" + month + "-" + day;
    }
}

 

 题目集4(7-2)采用依次继承的方法,这样设计的好处是思路清晰,逻辑性强,可以有条理的写下去,弊端是修改时比较麻烦,牵一发而动全身;题目集5(7-4)采用的是年、月、日的信息类都继承于dateutil计算类,它的好处是各个类 都有一定的独立性,封装性强在编写时可以按块分别写,修改时也只需改某个类而不需要大改,缺点是各个类都比较独立,写代码的时候可能不太连贯,要写很多重复的东西。针对这两次功能相同但是结构不一样的题目的总结是,前者是从上到下依次继承,其函数的耦合度较高,好处是可以让最后的那一个子类可以不需要重写父类的参数与方法,而后者则是定义年、月、日,分别视它们为单独的一个父类,而最后的那一个子类,去继承这些父类,也解决了不需要重写父类方法、参数的问题,而且相较于前者,后者的耦合度较低,方便代码的修改与查改,不会说一错全错,对于面向对象语言,耦合度越低越方便我们增加、删改代码,也能让程序相互独立,便于修改。所以对于后者是应该我们大家学习的写法。

 

  ②题目集4(7-3)、题目集6(7-5、7-6)三种渐进式图形继承设计的思路与技术运用(封装、继承、多态、接口等)

7-3 图形继承 (15 分)
 

编写程序,实现图形类的继承,并定义相应类对象并进行测试。

  1. 类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();//求立方体体积
  6. 注意:
  • 每个类均有构造方法,且构造方法内必须输出如下内容:Constructing 类名
  • 每个类属性均为私有,且必须有getter和setter方法(可用Eclipse自动生成)
  • 输出的数值均保留两位小数

主方法内,主要实现四个功能(1-4): 从键盘输入1,则定义圆类,从键盘输入圆的半径后,主要输出圆的面积; 从键盘输入2,则定义矩形类,从键盘输入矩形的宽和长后,主要输出矩形的面积; 从键盘输入3,则定义球类,从键盘输入球的半径后,主要输出球的表面积和体积; 从键盘输入4,则定义立方体类,从键盘输入立方体的宽、长和高度后,主要输出立方体的表面积和体积;

假如数据输入非法(包括圆、矩形、球及立方体对象的属性不大于0和输入选择值非1-4),系统输出Wrong Format

 

 

package demo;

import java.util.Scanner;
public class Test {
    public static void main(String[] args) {
    Scanner input = new Scanner(System.in);
            int i = input.nextInt();
            if(i == 1) {
                double r = input.nextDouble();
                if(r<=0.0) {
                    System.out.println("Wrong Format");
                }
                else {
                    Circle circle = new Circle();
                    circle.setRadius(r);
                    System.out.printf("Circle's area:%.2f",circle.getArea());
                }
            }
    
            else if(i == 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.printf("Rectangle's area:%.2f",rectangle.getArea());
                }
            }
            else if(i == 3) {
                double r1 = input.nextDouble();
                if(r1<=0.0)
                    System.out.println("Wrong Format");
                else{
                    Ball ball = new Ball();
                    ball.setRadius(r1);
                    System.out.printf("Ball's surface area:%.2f\n",ball.getArea());
                    System.out.printf("Ball's volume:%.2f",ball.getVolume());
                }
            }
            else if(i == 4) {
                double width1 = input.nextDouble();
                double length1 = input.nextDouble();
                double height = input.nextDouble();
                if(width1<=0.0 || length1<=0.0 || height<=0.0)
                    System.out.println("Wrong Format");
                else {
                    Box box = new Box();
                    box.setWidth(width1);
                    box.setLength(length1);
                    box.setHeight(height);
                    System.out.printf("Box's surface area:%.2f\n",box.getArea());
                    System.out.printf("Box's volume:%.2f",box.getVolume());
                }
            }
            else
                System.out.println("Wrong Format");
    }
}
class Shape{
        
    public Shape(){
        System.out.println("Constructing Shape");
    }
    public double getArea(){
            return 0.0;
        }
}


class Circle extends Shape{
    
    public Circle() {
        System.out.println("Constructing Circle");
    }
    private double radius;
    
    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 void setWidth(double width) {
        this.width = width;
    }
    public double getWidth() {
        return width;
    }
    
    public void setLength(double length) {
        this.length = length;
    }
    public double getLength() {
        return length;
    }
    
    public double getArea() {
        return length * width;
    }
}


class Ball extends Circle{
    
    public Ball(){
        System.out.println("Constructing Ball");
    }
    
    public double getArea() {
        return 4.0*super.getArea();
    }
    public double getVolume() {
        double r1 = getRadius();
        return (4.0/3.0)*r1*r1*r1*3.14;
    }
}


class Box extends Rectangle{
    public Box() {
        System.out.println("Constructing Box");
    }
    private double height;
    
    public void setHeight(double height) {
        this.height = height;
    }
    public double getHeight() {
        return height;
    }
    
    public double getVolume() {
        return height * super.getArea();
    }
    public double getArea() {
        double w1 = super.getWidth();
        double l1 = super.getLength();
        return w1*l1*2 + w1*height*2 + l1*height*2;
    }
}

 

 这道题我的思路是把从键盘输入的功能选项都放在主类的main方法中,然后采用继承的方式分别调用其它类中的方法实现所需功能,所运用 的技术是封装与继承;

题目集6(7-5)

图形继承与多态 (50 分)
 

掌握类的继承、多态性及其使用方法。具体需求参见作业指导书。

2021-OO第06次作业-5指导书V1.0.pdf

输入格式:

从键盘首先输入三个整型值(例如a b c),分别代表想要创建的Circle、Rectangle及Triangle对象的数量,然后根据图形数量继续输入各对象的属性值(均为实型数),数与数之间可以用一个或多个空格或回车分隔。

输出格式:

  1. 如果图形数量非法(小于0)或图形属性值非法(数值小于0以及三角形三边关系),则输出Wrong Format。
  2. 如果输入合法,则正常输出,输出内容如下(输出格式见输入输出示例):
  • 各个图形的面积;
  • 所有图形的面积总和;
  • 排序后的各个图形面积;
  • 再次所有图形的面积总和。

 

 

package demo;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.Scanner;

public class Test {
    public static void main(String[]args)
    {
        Scanner input = new Scanner(System.in);
        //创建三个对象
        Circle circle=new Circle();//d
        Rectangle rectangle=new Rectangle();//e
        Triangle triangle=new Triangle();//f
        int a=input.nextInt();
        int b=input.nextInt();
        int c=input.nextInt();
        if(a<0||b<0||c<0)
        {
            System.out.print("Wrong Format");
            System.exit(0);
        }
        int j=0;
        double SumArea=0;
        double Area[]=new double[a+b+c];
        for(int i=0;i<a;i++)
        {
            circle.setRadius(input.nextDouble());
            if(circle.isCircle()==false)
            {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            Area[j]=circle.getArea();
            j++;
        }
        for(int i=a;i<a+b;i++)
        {
            rectangle.Rectangle(input.nextDouble(), input.nextDouble());
            if(rectangle.isRectangle()==false)
            {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            Area[j]=rectangle.getArea();
            j++;
        }
        for(int i=a+b;i<a+b+c;i++)
        {
            triangle.Triangle(input.nextDouble(),input.nextDouble(),input.nextDouble());
            if(triangle.isTriangle()==false)
            {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            
            Area[j]=triangle.getArea();
            j++;
        }
        System.out.println("Original area:");
        for(int i=0;i<Area.length;i++)
        {
            System.out.printf("%.2f ",Area[i]);
                
                SumArea=SumArea+Area[i];
        }
         System.out.println();
         System.out.printf("Sum of area:");
         System.out.printf("%.2f\n",SumArea);
         Arrays.sort(Area);                      //Array中的方法,将数组中的数据按从小到大的顺序排序
        System.out.println("Sorted area:");
        for(int i=0;i<Area.length;i++)
          {            
            System.out.printf("%.2f ",Area[i]);                    
          }
        System.out.println("");
        System.out.printf("Sum of area:%.2f",SumArea);
    }
  
    }
    

    abstract class Shape {
        public abstract  double getArea();
    }

class Circle extends Shape                   //yuan
{
    private double radius;

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
    boolean isCircle(){
        if( radius>0) {
            return true;
        }
        else 
            return false;
    }
    public double getArea()
    {
        return Math.PI*getRadius()*getRadius();
    }
    
}

class Rectangle extends Shape {
    double width,length;
    
    public void Rectangle(double width, double length) {
      
        this.width = width;
        this.length = length;
    }
    
    public double getArea() {
        return width * length;
    }
    boolean isRectangle() {
        if( width > 0 && length > 0) {
            return true;
        }
        else
            return false;
    }
}
class Triangle extends Shape {                       //sanjiaoxing
    double a = 0, b = 0, c = 0;
    void Triangle(double a, double b, double c) {
        this.a = a;
        this.b = b;
        this.c = c;
    }
   
    public double getArea() {
        double z = (a + b + c) / 2;
        return Math.sqrt(z * (z - a) * (z - b) * (z - c));
    }
    boolean isTriangle() {
        if(a<=0||b<=0||c<=0)
            return false;
        else if(a+b>c&&a+c>b&&b+c>a)
            return true;
        else 
            return false ;
}
}

 

 getArea()方法为抽象方法,功能为求得图形的面积;validate()方法也为抽象方法,对图形的属 性进行合法性校验;toString()继承自 Object,功能为输出图形的面积信息,其格式参考输出示例。本次作 业我们采用的是抽象类定义、实体类构建的方式。即 Shape 为抽象类,Circle、Rectangle 及 Triangle为实体类,这道题运用的技术是继承,封装和多态等。

题目集6(7-6)

实现图形接口及多态性 (30 分)
 

编写程序,使用接口及类实现多态性,类图结构如下所示:

类图.jpg

其中:

  • GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法;
  • Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口
  • 要求:在Main类的主方法中分别定义一个圆类对象及矩形类对象(其属性值由键盘输入),使用接口的引用分别调用圆类对象及矩形类对象的求面积的方法,直接输出两个图形的面积值。(要求只保留两位小数)

输入格式:

从键盘分别输入圆的半径值及矩形的宽、长的值,用空格分开。

输出格式:

  • 如果输入的圆的半径值及矩形的宽、长的值非法(≤0),则输出Wrong Format
  • 如果输入合法,则分别输出圆的面积和矩形的面积值(各占一行),保留两位小数。

这道题和上道题十分的相似,但使用了接口这个概念实现多态性,GetArea为一个接口,无属性,只有一个GetArea(求面积)的抽象方法,Circle及Rectangle分别为圆类及矩形类,分别实现GetArea接口。

 

 

package demo;
import java.util.Scanner;

public class Test {
    public static void main(String[]args)
    {
        Scanner input = new Scanner(System.in);
        //创建2个对象
        Circle circle=new Circle();//d
        Rectangle rectangle=new Rectangle();//e

            circle.setRadius(input.nextDouble());
            rectangle.Rectangle(input.nextDouble(), input.nextDouble());
            if(circle.isCircle()==false||rectangle.isRectangle()==false)
            {
                System.out.println("Wrong Format");
                System.exit(0);
            }
            else if(circle.isCircle()==true&&rectangle.isRectangle()==true){
            System.out.printf("%.2f",circle.getArea());
            System.out.println();
            System.out.printf("%.2f",rectangle.getArea());
        }            
                    }         
        
    }

    abstract class Shape {
        public abstract  double getArea();
    }

class Circle extends Shape                   //yuan
{
    private double radius;

    public double getRadius() {
        return radius;
    }

    public void setRadius(double radius) {
        this.radius = radius;
    }
    boolean isCircle(){
        if( radius>0) {
            return true;
        }
        else 
            return false;
    }
    public double getArea()
    {
        return Math.PI*getRadius()*getRadius();
    }
    
}

class Rectangle extends Shape {
    double width,length;
    
    public void Rectangle(double width, double length) {
      
        this.width = width;
        this.length = length;
    }
    
    public double getArea() {
        return width * length;
    }
    boolean isRectangle() {
        if( width > 0 && length > 0) {
            return true;
        }
        else
            return false;
    }
}

 

 ③对三次题目集中用到的正则表达式技术的分析总结

题目集4(7-1)中需用字符串处理类以及正则表达式对输入字符串数据进行合法性校验及计算,这题我个人认为难度太大,过程有点繁琐,用正则表达式校检之后还要结合字符串方法进行提取分割;

题目集5(7-4)需用正则表达式统计一个输入的Java源码中关键字(区分大小写)出现的次数。首先用字符串把54个关键字存进去,然后用正则表达式识别关键字并统计出现次数,这题难度适中;

题目集6(7-1)要求使用正则表达式判断输入的QQ号是否合格,这题使用简单的正则表达式就可以解决,难度小;

package demo;
import java.util.Scanner;
public class Test {         
    public static void main(String[] args) {  
            Scanner input = new Scanner(System.in);  
            String QQID = input.nextLine();  
            String regex = "[1-9][0-9]{4,14}";  
            boolean flag = QQID.matches(regex);  
            if (flag==true) {  
                System.out.println("你输入的QQ号验证成功");  
            }
            else {  
                System.out.println("你输入的QQ号验证失败");  
            }  
             
        }  
       
    }

 

 题目集6(7-3)要求接受给定的字符串,然后用正则表达式判断该字符串是否属于验证码,这:题和上一题结果基本相似,只是在正则表达式的表示方面更进一步了

package demo;
import java.util.Scanner;
public class Test {         
    public static void main(String[] args) {  
            Scanner input = new Scanner(System.in);  
            String Captcha = input.nextLine();  
            String regex = "\\w";  
            boolean flag = Captcha.matches(regex);  
            if (flag==true) {  
                System.out.println(Captcha+"属于验证码");  
            }
            else {  
                System.out.println(Captcha+"不属于验证码");  
            }  
    } 
        }  

 

 题目集6(7-4)需要对学生学号进行校检,大体结构也和前面两题相同,只是正则表达式不同:“ "[2020]([11-17]|([6][1])|[7][1-3]|[8][1-2])[01-40]"”把正则表达式改成这样差不多就行了;

三个题目集所用到的正则表达式技术都相对基础,尤其是题目集六的那三个正则表达式题目,可以说是非常简单了,都是直接用正则表达式表示出简单的数字或字母然后进行校检

三、踩坑心得

在写题目集6(7-5)时一开始光顾着创建对象数组而忘记了分配空间,就导致测试点一直过不了;写题目集6(7-2)时,虽然思路十分清晰,但还是有些问题,刚开始我想用import java.util.Arrays;类中的Arrays.sort()方法,但就是没有输出结果,后来改用冒泡排序法,由于太久没用过了有些细节没处理好,又没有输出,然后调试发现前面将字符串转化为数组的代码没有问题,就是排序错了,最后也是艰难的完成了这题

 

 还有就是题目集6的那三个正则表达式题目,由于前面的与正则表达式有关的题目我觉得做不出来就没有去做,正则表达式我也是没怎么学,然后做这三题的时候一边学一边做,虽然这个过程不是很坎坷,但如果之前认真尝试了那些题目的话,那做这三题应该会快很多,所以以后还是要多花时间去学习课本以外的知识;

题目集5(7-3)要用到三种排序方法进行排序,之前课程学习中我认为学了一种就够了,别的就没怎么学,现在做这题也感觉到了吃力;这些题最让我印象深刻的就是题目集5(7-4)了,我一开始不会做,就想着先随便写点东西上去看看能不能得点分

 

 

 

 结果就有了这一意外惊喜,所以以后不会做的题还是不要乱写的好。

四、改进建议


我觉得老师出的题目非常好,很完美,没什么改进建议。

五、总结

通过这三次题目集,我主要学到了继承技术,正则表达式的简单应用,还有一些简单数组方法的使用,如以前想要对数组里的数值进行排序,我首先想到的是冒泡排序等,这样就比较麻烦,但用import java.util.Arrays;类中的Arrays.sort()方法就可以一步到位,十分的方便快捷,其它如聚合,多态,接口这样的虽然也有,但是还是很不熟悉,需要进一步学习和研究,还有数组方法也要多研究,增长知识的同时也可以让以前要写一大坨的东西一个语句就搞定,正则表达式也要再去摸索摸索,现在只会一些简单的如数字字母范围的表示,稍微复杂一点如特殊字符就不会了。

posted @ 2021-05-01 14:33  gjl1  阅读(94)  评论(0)    收藏  举报