题目集4、5及期中考试总结

  • 前言:

第四、第五次大作业题目主要是对java面向对象程三大支柱的应用:封装、继承和多态。题量适中、难度适中。封装使得程序的测试变得更加有目的性,继承和多态的组合则是面向对象程序设计的灵魂所在。
  • 设计与分析:

    • 第四次作业 

      • 用户输入一组选项和数据,进行与四边形有关的计算。
        以下四边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
        选项包括:
        1:输入四个点坐标,判断是否是四边形、平行四边形,判断结果输出true/false,结果之间以一个英文空格符分隔。
        2:输入四个点坐标,判断是否是菱形、矩形、正方形,判断结果输出true/false,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
        3:输入四个点坐标,判断是凹四边形(false)还是凸四边形(true),输出四边形周长、面积,结果之间以一个英文空格符分隔。 若四个点坐标无法构成四边形,输出"not a quadrilateral"
        4:输入六个点坐标,前两个点构成一条直线,后四个点构成一个四边形或三角形,输出直线与四边形(也可能是三角形)相交的交点数量。如果交点有两个,再按面积从小到大输出四边形(或三角形)被直线分割成两部分的面积(不换行)。若直线与四边形或三角形的一条边线重合,输出"The line is coincide with one of the lines"。若后四个点不符合四边形或三角形的输入,输出"not a quadrilateral or triangle"。
        后四个点构成三角形的情况:假设三角形一条边上两个端点分别是x、y,边线中间有一点z,另一顶点s:
        1)符合要求的输入:顶点重复或者z与xy都相邻,如x x y s、x z y s、x y x s、s x y y。此时去除冗余点,保留一个x、一个y。
        2) 不符合要求的输入:z 不与xy都相邻,如z x y s、x z s y、x s z y
        5:输入五个点坐标,输出第一个是否在后四个点所构成的四边形(限定为凸四边形,不考虑凹四边形)或三角形(判定方法见选项4)的内部(若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。如果点在多边形的某条边上,输出"on the triangle或者on the quadrilateral"。若后四个点不符合四边形或三角形,输出"not a quadrilateral or triangle"。
      • 输入格式:

        基本格式:选项+":"+坐标x+","+坐标y+" "+坐标x+","+坐标y。点的x、y坐标之间以英文","分隔,点与点之间以一个英文空格分隔。

      • 输出格式:

        基本输出格式见每种选项的描述。
        异常情况输出:
        如果不符合基本格式,输出"Wrong Format"。
        如果符合基本格式,但输入点的数量不符合要求,输出"wrong number of points"。
        注意:输出的数据若小数点后超过3位,只保留小数点后3位,多余部分采用四舍五入规则进到最低位。小数点后若不足3位,按原始位数显示,不必补齐。例如:1/3的结果按格式输出为 0.333,1.0按格式输出为1.0

        选项1、2、3中,若四边形四个点中有重合点,输出"points coincide"。
        选项4中,若前两个输入线的点重合,输出"points coincide"。

          
         个人认为本题的难点在于判断输入是否为四边形以及4和5选项对输入坐标进行是三角形还是四边形的区分;

          

           经过对函数的拆分使得平均复制度和最大复杂度都处在相对合理的范围之内

           其中最主要的拆分是针对主函数的拆分使得最大复杂度较之上次有明显下降,并且为代码的加上了注释,大大提高了代码的可读性,主类代码如下:

复制代码
  1 public class Main {
  2     public static void main(String[] args) {
  3         Processing input = new Processing();
  4         try {
  5         input.isLegal();    
  6         Point[] p = input.createPointArray(input.whichCase());
  7         switch(input.whichCase()) {
  8         case 1:
  9             condition1(p);
 10             break;
 11         case 2:
 12             condition2(p);
 13             break;
 14         case 3:
 15             condition3(p);        
 16             break;
 17         case 4:
 18             condition4(p);        
 19             break;
 20         case 5:
 21             condition5(p);        
 22             break;
 23             } 
 24         }
 25         catch (IllegalArgumentException ex) {
 26 
 27             System.out.println(ex.getMessage());
 28         }
 29     }
 30 
 31     private static void condition5(Point[] p) {
 32         Point[] vertex = new Point[4];
 33         System.arraycopy(p, 1, vertex, 0, vertex.length);
 34         Polygon polygon = Polygon.distinguish(vertex);
 35         String string1 = null;
 36         if (polygon instanceof Triangle)
 37             string1 = "triangle";
 38         else
 39             string1 = "quadrilateral";
 40         String string2 = null;
 41         if(polygon.isPointOnPolygon(p[0]))
 42             string2 = "on the ";
 43         else if(polygon.isPointInPolygon(p[0]))
 44             string2 = "in the ";
 45         else
 46             string2 = "outof the ";
 47 
 48         System.out.println(string2 + string1);
 49     }
 50 
 51     private static void condition4(Point[] p) {
 52         Line l = new Line(p[0],p[1]);
 53         Point[] points = new Point[4];
 54         System.arraycopy(p, 2, points, 0, points.length);
 55         Polygon polygon = Polygon.distinguish(points);
 56         polygon.isLineCoincideWithEdge(l);
 57         
 58         Point[] intersection = polygon.intersectionOfLineAndPolygon(l);
 59         String s = polygon.intersectionOfLineAndPolygon(l).length + "";
 60         if(intersection.length == 2) {
 61             s = condition4GetArea(s,polygon,l,intersection);
 62         }
 63         System.out.println(s);
 64     }
 65     /* 处理选项四需要求面积的情况 */
 66     private static String condition4GetArea(String s, Polygon polygon,Line l,Point[] intersection) {
 67         Point[] m = polygon.whichSideOfLine(l);
 68         Polygon t = null;
 69         
 70         switch (m.length) {
 71         case 1: {
 72             Point[] vertex = {intersection[0],intersection[1],m[0]};
 73             t = new Triangle(vertex);            
 74             break;            
 75         }
 76         case 2: {
 77             Point[] vertex = {intersection[1],intersection[0],m[0],m[1]};
 78             t = new Quadrilateral(vertex);
 79             break;            
 80         }
 81         default:{
 82 
 83         }
 84         }
 85         double[] area = new double[2];
 86         area[0] = t.getArea();
 87         area[1] = polygon.getArea() - area[0];
 88         area[0] = Processing.rounding(area[0]);
 89         area[1] = Processing.rounding(area[1]);
 90         String s1 = s + " " + Math.min(area[0], area[1]) + " " + Math.max(area[0], area[1]);
 91         return s1;
 92     }
 93 
 94     private static void condition3(Point[] p) {
 95         Quadrilateral q = new Quadrilateral(p);
 96         double perimeter = Processing.rounding(q.getPerimeter());
 97         double area = Processing.rounding(q.getArea());
 98         System.out.println(q.isConvexPolygon() + " " + perimeter + " " + area);
 99     }
100 
101     private static void condition2(Point[] p) {
102         Quadrilateral q = new Quadrilateral(p);    
103         System.out.println(q.isDiamond() + " " + q.isRectangle() + " " + q.isSquare());
104     }
105 
106     private static void condition1(Point[] p) {
107         Quadrilateral q = null;
108         boolean isQuadrilateral = false;
109         boolean isParallelogram = false;
110         try {
111              q = new Quadrilateral(p);
112              isQuadrilateral = Quadrilateral.isQuadrilateral(p,q.edge);
113              isParallelogram = q.isParallelogram();
114         }
115         catch (IllegalArgumentException ex) {
116         }
117         finally {
118             if(Polygon.isPolygon2(p))
119                 throw new IllegalArgumentException("points coincide");
120             System.out.println(isQuadrilateral + " " + isParallelogram);
121         }
122     }
123 }
复制代码

    代码的编写加入了Java抛出错误的特性,使得题目中各式各样的错误输入能够更加简洁地输出提示信息。在各个类中分别判断自己需要辨别的错误输入类型,最后再在主类中统一catch,显示错误信息,大大缩减了if-else分支条件判断。

    题中一选项判断是否构成四边形是一个重要的判断,所以在相应类中也是抛出错误,所以为了使得一选项能够正确地显示不构成四边形的情况(false),而不是显示错误提示(not a quadrilateral),在condition1函数中增加了一个catch补捉错误但不做任何处理,达到能够输出false的目的。

     

 

 

 抽象类多边形类Polygon为四边形类Quadrilateral和三角形类Triangle父类,四边形和三角形所共有的方法,例如:求一个点是否在多边形内、求周长、求面积(抽象方法)都定义在多边形类内部。在4、5选项中即可运用Java的多态特性简化代码。

能否构成四边形要做以下三个判断:1.是否有三点在同一直线上;2.是否有任意两点重合;3.连续输入的点在多边形中是否相邻;进行这三个判断后即可判断输入的四个点能否构成四边形,代码如下:

复制代码
 1 /*判断是否有任意三点在同一直线上:输入:Point数组;输出:有:true;无:false */
 2     static boolean isPolygon1(Point[] p) {
 3         boolean index = false;
 4         for (int i = 0; i < p.length; i++)
 5             for (int j = i + 1; j < p.length; j++)
 6                 for (int k = j + 1; k < p.length; k++)
 7                     if(Line.isInALine(p[i],p[j],p[k]))
 8                         index = true;
 9         return index;
10     }
11     /*判断是否有任意两点重合:输入:Point数组;输出:有:true;无:false */
12     static boolean isPolygon2(Point[] p) {
13         boolean index = false;
14         for (int i = 0; i < p.length; i++) 
15             for (int j = i + 1; j < p.length; j++) 
16                 if (p[i].isCoincide(p[j])) 
17                     index = true;
18         return index;
19     }
20     /*判断所以连续输入的点在多边形中是否存相邻:输入:Line数组;输出:相邻:true;不相邻:false */
21     static boolean isPolygon3(Line[] l) {
22         boolean index = true;
23         for (int i = 0; i < l.length; i++) {
24             if(l[i].isIntersectionOnSegment(l[(i + 2) % l.length]))
25                 index = false;
26         }
27         return index;
28         
29     }
复制代码

 

比较难的一点就是如何判断所输入的四个点是否能按照要求构成三角形或四边形。我所采取的方法为先判断能否构成四边形。然后,如果不能构成四边形再判断能否构成三角形。

去除重复点后,若存在连续三点不在同一直线上,则不能构成三角形。判断代码如下:

复制代码
/* 判断四点能否按要求构成三角形:若不能,则抛出错误;若能,则返回所构成三角形的顶点 */
    static Point[] isTriangle(Point[] p) throws IllegalArgumentException{
        Point[] newPoints = new Point[NUMBER_OF_EDGE];
        ArrayList<Point> pointsList = new ArrayList<>(Arrays.asList(p));
        //去除重复点
        for (int i = 0; i < pointsList.size(); i++) {
            for (int j = i + 1; j < pointsList.size(); j++) {
                if(pointsList.get(i).isCoincide(pointsList.get(j))) {
                    pointsList.remove(j);
                    continue;
                }
            }
        }
        //去除在线段上的点
        for (int i = 0; i < pointsList.size(); i++) {
            int j = (i + 1) % pointsList.size();
            int k = (i - 1 + pointsList.size()) % pointsList.size();
            Line l = new Line(pointsList.get(j), pointsList.get(k));
            if (l.isPointOnLine(pointsList.get(i)) && l.isOnSegment(pointsList.get(i))) {
                pointsList.remove(i);
            }
        }

        if(pointsList.size() == NUMBER_OF_EDGE)
            pointsList.toArray(newPoints);
        else
            throw new IllegalArgumentException("not a triangle");
        return newPoints;
    }
}
复制代码

求分割后两部分面积的方法为:先求出顶点在直线两侧每一侧的数量,在用较少的一侧的点和交点来构成多边形。这样做就把多种情况划分为两种:1.一个点;2.两个点。这两种情况和交点分别构成三角形和四边形,求出这一部分面积后再用原面积减去这部分即可得到另一部分的面积。代码如下:

复制代码
/* 处理选项四需要求面积的情况 */
    private static String condition4GetArea(String s, Polygon polygon,Line l,Point[] intersection) {
        Point[] m = polygon.whichSideOfLine(l);
        Polygon t = null;
        
        switch (m.length) {
        case 1: {
            Point[] vertex = {intersection[0],intersection[1],m[0]};
            t = new Triangle(vertex);            
            break;            
        }
        case 2: {
            Point[] vertex = {intersection[1],intersection[0],m[0],m[1]};
            t = new Quadrilateral(vertex);
            break;            
        }
        default:{

        }
        }
        double[] area = new double[2];
        area[0] = t.getArea();
        area[1] = polygon.getArea() - area[0];
        area[0] = Processing.rounding(area[0]);
        area[1] = Processing.rounding(area[1]);
        String s1 = s + " " + Math.min(area[0], area[1]) + " " + Math.max(area[0], area[1]);
        return s1;
    }
复制代码

剩下部分相对简单,不做过多介绍,完整代码如下:

      

复制代码
  1 package four72;
  2 
  3 import java.util.Scanner;
  4 import java.util.ArrayList;
  5 import java.util.Arrays;
  6 
  7 public class Main {
  8     public static void main(String[] args) {
  9         Processing input = new Processing();
 10         try {
 11         input.isLegal();    
 12         Point[] p = input.createPointArray(input.whichCase());
 13         switch(input.whichCase()) {
 14         case 1:
 15             condition1(p);
 16             break;
 17         case 2:
 18             condition2(p);
 19             break;
 20         case 3:
 21             condition3(p);        
 22             break;
 23         case 4:
 24             condition4(p);        
 25             break;
 26         case 5:
 27             condition5(p);        
 28             break;
 29             } 
 30         }
 31         catch (IllegalArgumentException ex) {
 32 
 33             System.out.println(ex.getMessage());
 34         }
 35     }
 36 
 37     private static void condition5(Point[] p) {
 38         Point[] vertex = new Point[4];
 39         System.arraycopy(p, 1, vertex, 0, vertex.length);
 40         Polygon polygon = Polygon.distinguish(vertex);
 41         String string1 = null;
 42         if (polygon instanceof Triangle)
 43             string1 = "triangle";
 44         else
 45             string1 = "quadrilateral";
 46         String string2 = null;
 47         if(polygon.isPointOnPolygon(p[0]))
 48             string2 = "on the ";
 49         else if(polygon.isPointInPolygon(p[0]))
 50             string2 = "in the ";
 51         else
 52             string2 = "outof the ";
 53 
 54         System.out.println(string2 + string1);
 55     }
 56 
 57     private static void condition4(Point[] p) {
 58         Line l = new Line(p[0],p[1]);
 59         Point[] points = new Point[4];
 60         System.arraycopy(p, 2, points, 0, points.length);
 61         Polygon polygon = Polygon.distinguish(points);
 62         polygon.isLineCoincideWithEdge(l);
 63         
 64         Point[] intersection = polygon.intersectionOfLineAndPolygon(l);
 65         String s = polygon.intersectionOfLineAndPolygon(l).length + "";
 66         if(intersection.length == 2) {
 67             s = condition4GetArea(s,polygon,l,intersection);
 68         }
 69         System.out.println(s);
 70     }
 71     /* 处理选项四需要求面积的情况 */
 72     private static String condition4GetArea(String s, Polygon polygon,Line l,Point[] intersection) {
 73         Point[] m = polygon.whichSideOfLine(l);
 74         Polygon t = null;
 75         
 76         switch (m.length) {
 77         case 1: {
 78             Point[] vertex = {intersection[0],intersection[1],m[0]};
 79             t = new Triangle(vertex);            
 80             break;            
 81         }
 82         case 2: {
 83             Point[] vertex = {intersection[1],intersection[0],m[0],m[1]};
 84             t = new Quadrilateral(vertex);
 85             break;            
 86         }
 87         default:{
 88 
 89         }
 90         }
 91         double[] area = new double[2];
 92         area[0] = t.getArea();
 93         area[1] = polygon.getArea() - area[0];
 94         area[0] = Processing.rounding(area[0]);
 95         area[1] = Processing.rounding(area[1]);
 96         String s1 = s + " " + Math.min(area[0], area[1]) + " " + Math.max(area[0], area[1]);
 97         return s1;
 98     }
 99 
100     private static void condition3(Point[] p) {
101         Quadrilateral q = new Quadrilateral(p);
102         double perimeter = Processing.rounding(q.getPerimeter());
103         double area = Processing.rounding(q.getArea());
104         System.out.println(q.isConvexPolygon() + " " + perimeter + " " + area);
105     }
106 
107     private static void condition2(Point[] p) {
108         Quadrilateral q = new Quadrilateral(p);    
109         System.out.println(q.isDiamond() + " " + q.isRectangle() + " " + q.isSquare());
110     }
111 
112     private static void condition1(Point[] p) {
113         Quadrilateral q = null;
114         boolean isQuadrilateral = false;
115         boolean isParallelogram = false;
116         try {
117              q = new Quadrilateral(p);
118              isQuadrilateral = Quadrilateral.isQuadrilateral(p,q.edge);
119              isParallelogram = q.isParallelogram();
120         }
121         catch (IllegalArgumentException ex) {
122         }
123         finally {
124             if(Polygon.isPolygon2(p))
125                 throw new IllegalArgumentException("points coincide");
126             System.out.println(isQuadrilateral + " " + isParallelogram);
127         }
128     }
129 }
130 
131 class Processing {
132     private String s;
133     Processing() {
134         Scanner input = new Scanner(System.in);
135         s = input.nextLine();
136         input.close();
137     }
138     /* 判断输入是否符合格式,不符合则抛出错误 */
139     void isLegal() throws IllegalArgumentException{
140         String S = "[+-]?((0|[1-9][\\d]*)([\\.][\\d]+)?)";
141         String REGEX = "[1-5]:" + S + "," + S + "(\\s" + S +","+ S + ")*[\\s]*";
142         if(!s.matches(REGEX))
143             throw new IllegalArgumentException("Wrong Format");
144     }
145     int whichCase() {
146         return s.charAt(0) - '0';
147     }
148 
149     /* 从字符串中提取坐标 */
150     Point[] getCoordinates(int n) {
151         Point[] a = new Point[n];
152         String[] tokens = s.split(":");
153         String[] coordinate = tokens[1].split("\\s");
154         for(int i = 0;i < n;i++) {
155             String[] number = coordinate[i].split(",");
156             a[i] = new Point(Double.parseDouble(number[0]),Double.parseDouble(number[1]));
157         }
158         return a;
159     }
160     /* 用提取的坐标创建Point数组并返回,若点的数量不对则抛出错误 */
161     Point[] createPointArray(int condition) throws IllegalArgumentException {
162         Point[] p = null;
163         int[] numberOfPoint = {4,4,4,6,5};
164         if(numberOfPoints() == numberOfPoint[condition - 1]) {
165             p = getCoordinates(numberOfPoint[condition - 1]);
166             return p;
167         }
168         else {
169             throw new IllegalArgumentException("wrong number of points");
170         }
171         
172     }
173     /* 返回字符串中点的数量 */
174     int numberOfPoints() {
175         String[] tokens = this.s.split("\\s");
176         return tokens.length;
177     }
178     /* 进行四舍五入 */
179     static double rounding(double x) {
180         return (int)(x * 1e3 + 0.5) / 1e3 / 1.0;
181     }
182 }
183 
184 class Point {
185     private double x,y;
186     Point() {
187         this(0, 0);
188     }
189     Point(double x,double y) {
190         this.x = x;
191         this.y = y;
192     }
193     void setX(double newX) {
194         x = newX;
195     }
196     void setY(double newY) {
197         y = newY;
198     }
199     double getX() {
200         return x;
201     }
202     double getY() {
203         return y;
204     }
205     double distance(Point a) {
206         double distance = Math.sqrt(Math.pow(this.x - a.x,2) + Math.pow(this.y - a.y,2));
207         return distance;
208     }
209     boolean isCoincide(Point a) {
210         return (Math.abs(this.x - a.x) < 1e-6 && Math.abs(this.y - a.y) < 1e-6);
211     }
212 }
213 
214 class Line {
215     private Point a,b;
216     private double A,B,C;    //ֱ直线一般方程的参数
217     Line(Point a,Point b) {
218         this.a = a;
219         this.b = b;
220         A = b.getY() - a.getY();
221         B = a.getX() - b.getX();
222         C = b.getX() * a.getY() - a.getX() * b.getY() ;
223     }
224     double slope() {
225         double k = -A / B;
226         return k;
227     }
228     double distancFromPointToLine(Point a) {
229         double distance = Math.abs(A * a.getX() + B * a.getY() + C) / Math.sqrt(Math.pow(A,2) + Math.pow(B,2));
230         return distance;
231     }
232     /* 判断点是否在直线上:是:true;否:false */
233     boolean isPointOnLine(Point a) {
234         return (Math.abs(A * a.getX() + B * a.getY() + C) < 1e-5);
235     }
236     /* 判断两直线是否平行 */
237     boolean isParallel(Line a) {
238         return (Math.abs(this.A * a.B - a.A * this.B) < 1e-5);
239     }
240     /* 求两条直线的交点 */
241     Point intersectionOfTwoLines(Line a) {
242         Point intersection;
243         double denominator = this.A * a.B - a.A * this.B;
244         if(Math.abs(denominator) < 1e-6)
245             intersection = null;
246         else {
247             double x = -(a.B * this.C - this.B * a.C) / denominator;
248             double y = -(this.A * a.C - a.A * this.C) / denominator;
249             intersection = new Point(x,y);
250         }
251         return intersection;
252     }
253     /* 判断点是否在线段上:是:true;否:false */
254     boolean isOnSegment(Point q) {
255         return (Math.min(a.getX() , b.getX()) <= q.getX() && q.getX() <= Math.max(a.getX() , b.getX())    
256         && Math.min(a.getY() , b.getY()) <= q.getY() && q.getY() <= Math.max(a.getY() , b.getY()));
257     }
258     /* 判断两直线交点是否在线段上:是:true;否:false */
259     boolean isIntersectionOnSegment(Line l) {
260         boolean index = false;
261         Point intersection = intersectionOfTwoLines(l);
262         if(intersection != null)
263             index = (isOnSegment(intersection) && l.isOnSegment(intersection));
264         return index;
265         
266     }
267     /* 判断在直线的哪一侧 */
268     int whichSideOfLine(Point q) {
269         if(A * q.getX() + B * q.getY() + C > 0)
270             return 1;
271         else if(A * q.getX() + B * q.getY() + C < 0)
272             return 2;
273         else
274             return 3;
275     }
276     /* 判断两直线是否垂直 */
277     boolean isPerpendicular(Line l) {
278         return (Math.abs(A * l.A + B * l.B) < 1e-5);
279     }
280     static boolean isInALine(Point a,Point b,Point c) {
281         if(a.isCoincide(b) || a.isCoincide(c) || b.isCoincide(c))
282             return true;
283         else {
284             Line l = new Line(a,b);
285             if(l.isPointOnLine(c))
286                 return true;
287             else
288                 return false;
289         }
290     }
291     /* 判断两直线是否重合 */
292     boolean isLineCoincideWithLine(Line l) {
293         return (isParallel(l) && isPointOnLine(l.a));
294     }
295     /* 求线段中点 */
296     Point getMidpoint() {
297         Point midPoint = new Point((a.getX() + b.getX()) / 2,(a.getY() + b.getY()) / 2);
298         return midPoint;
299     }
300     /* 求线段长度 */
301     double getLength() {
302         double length = a.distance(b);
303         return length;
304         
305     }
306 }
307 
308 class Triangle extends Polygon{
309     static final int NUMBER_OF_EDGE = 3;
310     Triangle(Point[] vertex) {
311         super(NUMBER_OF_EDGE);
312         super.setVertex(vertex);
313         super.setEdge();
314     }
315     boolean isEquilateral() {
316         return (Math.abs(edgeLength[0] - edgeLength[1]) < 1e-6 && Math.abs(edgeLength[0] - edgeLength[2]) < 1e-6 && Math.abs(edgeLength[1] - edgeLength[2]) < 1e-6);
317     }
318     boolean isIsosceles() {
319         return (Math.abs(edgeLength[0] - edgeLength[1]) < 1e-6 || Math.abs(edgeLength[0] - edgeLength[2]) < 1e-6 || Math.abs(edgeLength[1] - edgeLength[2]) < 1e-6);
320     }
321     double getArea() {
322         double p = getPerimeter() / 2;
323         double s = Math.sqrt(p * (p - edgeLength[0]) * (p - edgeLength[1]) * (p - edgeLength[2])) ;
324         return s;
325     }
326     Point centerOfGravity() {
327         double x = (vertex[0].getX() + vertex[1].getX() + vertex[2].getX()) / 3;
328         double y = (vertex[0].getY() + vertex[1].getY() + vertex[2].getY()) / 3;
329         Point g = new Point(x,y);
330         return g;
331     }
332     boolean isObtuse() {
333         return (Math.pow(edgeLength[0],2) + Math.pow(edgeLength[1],2) - Math.pow(edgeLength[2],2) < 0);
334      }
335     boolean isRight() {
336         return (!this.isObtuse() && !this.isAcute());
337         //return (Math.pow(x,2) + Math.pow(y,2) == Math.pow(z,2));
338     }
339     boolean isAcute() {
340         return (Math.pow(edgeLength[0],2) + Math.pow(edgeLength[1],2) - Math.pow(edgeLength[2],2) > 0);
341     }
342     /* 判断点是否和顶点重合 */
343     boolean isCoincideWithVertex(Point q) {
344         boolean index = false;
345         for(int i = 0;i < NUMBER_OF_EDGE;i++) 
346             if(q.isCoincide(this.getVertex()[i]))
347                 index = true;
348         return index;
349     }
350     /* 判断四点能否按要求构成三角形:若不能,则抛出错误;若能,则返回所构成三角形的顶点 */
351     static Point[] isTriangle(Point[] p) throws IllegalArgumentException{
352         Point[] newPoints = new Point[NUMBER_OF_EDGE];
353         ArrayList<Point> pointsList = new ArrayList<>(Arrays.asList(p));
354         //去除重复点
355         for (int i = 0; i < pointsList.size(); i++) {
356             for (int j = i + 1; j < pointsList.size(); j++) {
357                 if(pointsList.get(i).isCoincide(pointsList.get(j))) {
358                     pointsList.remove(j);
359                     continue;
360                 }
361             }
362         }
363         //去除在线段上的点
364         for (int i = 0; i < pointsList.size(); i++) {
365             int j = (i + 1) % pointsList.size();
366             int k = (i - 1 + pointsList.size()) % pointsList.size();
367             Line l = new Line(pointsList.get(j), pointsList.get(k));
368             if (l.isPointOnLine(pointsList.get(i)) && l.isOnSegment(pointsList.get(i))) {
369                 pointsList.remove(i);
370             }
371         }
372 
373         if(pointsList.size() == NUMBER_OF_EDGE)
374             pointsList.toArray(newPoints);
375         else
376             throw new IllegalArgumentException("not a triangle");
377         return newPoints;
378     }
379 }
380 
381 
382 class Quadrilateral extends Polygon{
383     static final int NUMBER_OF_EDGE = 4;
384     public Quadrilateral(Point[] vertex) throws IllegalArgumentException{
385         super(NUMBER_OF_EDGE);
386         super.setVertex(vertex);
387         super.setEdge();        
388         if(!Quadrilateral.isQuadrilateral(vertex,edge))
389             throw new IllegalArgumentException("not a quadrilateral");
390     }
391     /* 判断是否为平行四边形:输入:无;输出:是:true;否:false */
392     boolean isParallelogram() {
393         return (edge[0].isParallel(edge[2]) && edge[1].isParallel(edge[3]));
394     }
395     /*判断是否为四边形:输入:一组点和一组直线;输出:是:true;否:false */
396     static boolean isQuadrilateral(Point[] p,Line[] l) {
397         return !Quadrilateral.isPolygon1(p) && !Quadrilateral.isPolygon2(p) && Quadrilateral.isPolygon3(l);
398     }
399     /* 判断是否为菱形:输入:无;输出:是:true;否:false */
400     boolean isDiamond() {
401         boolean index = true;
402         for (int i = 0; i < NUMBER_OF_EDGE; i++) {
403             int j = (i + 1) % NUMBER_OF_EDGE;
404             if(edgeLength[i] != edgeLength[j])
405                 index = false;
406         }
407         return index;
408     }
409     /* 判断是否为矩形:输入:无;输出:是:true;否:false */
410     boolean isRectangle() {
411         boolean index = false;
412         boolean isRight = false;
413         for (int i = 0; i < NUMBER_OF_EDGE; i++) {
414             int j = (i + 1) % NUMBER_OF_EDGE;
415             if(edge[i].isPerpendicular(edge[j]))
416                 isRight = true;
417         }
418         index = (isRight && isParallelogram());
419         return index;
420     }
421     /* 判断是否为正方形:输入:无;输出:是:true;否:false */
422     boolean isSquare() {
423         boolean index = false;
424         if(isDiamond() && isRectangle())
425             index = true;
426         return index;
427     }
428     double getArea() {
429         /* 不相邻两边中点的连线长乘以另两边的任一中点到该连线距离的2倍 */
430         Line l = new Line(edge[0].getMidpoint(),edge[2].getMidpoint());
431         double distance = l.distancFromPointToLine(edge[1].getMidpoint());
432         double area = 2 * distance * l.getLength();
433         return area;
434     }
435 }
436 
437 abstract class Polygon{    
438     protected Point[] vertex;                //顶点
439     protected double[] edgeLength;            //边长
440     protected int numberOfEdge;                //边数
441     protected Line[] edge;                    //
442     public Polygon(int numberOfEdge) {
443         this.numberOfEdge = numberOfEdge;
444         vertex = new Point[numberOfEdge];
445         edgeLength = new double[numberOfEdge];
446         edge = new Line[numberOfEdge];
447 
448     }
449     void setEdge() {
450         for(int i = 0;i < numberOfEdge;i++) {
451             edgeLength[i] = vertex[i].distance(vertex[(i + 1) % numberOfEdge]);
452             edge[i] = new Line(vertex[i],vertex[(i + 1) % numberOfEdge]);
453         }
454         Arrays.sort(edgeLength);
455     }
456     Point[] getVertex() {
457         return vertex;
458     }
459     void setVertex(Point[] vertex){
460             this.vertex = vertex;
461     }
462     int getNumberOfEdge() {
463         return numberOfEdge;
464     }
465     /*判断是否有任意三点在同一直线上:输入:Point数组;输出:有:true;无:false */
466     static boolean isPolygon1(Point[] p) {
467         boolean index = false;
468         for (int i = 0; i < p.length; i++)
469             for (int j = i + 1; j < p.length; j++)
470                 for (int k = j + 1; k < p.length; k++)
471                     if(Line.isInALine(p[i],p[j],p[k]))
472                         index = true;
473         return index;
474     }
475     /*判断是否有任意两点重合:输入:Point数组;输出:有:true;无:false */
476     static boolean isPolygon2(Point[] p) {
477         boolean index = false;
478         for (int i = 0; i < p.length; i++) 
479             for (int j = i + 1; j < p.length; j++) 
480                 if (p[i].isCoincide(p[j])) 
481                     index = true;
482         return index;
483     }
484     /*判断所以连续输入的点在多边形中是否存相邻:输入:Line数组;输出:相邻:true;不相邻:false */
485     static boolean isPolygon3(Line[] l) {
486         boolean index = true;
487         for (int i = 0; i < l.length; i++) {
488             if(l[i].isIntersectionOnSegment(l[(i + 2) % l.length]))
489                 index = false;
490         }
491         return index;
492         
493     }
494     Line[] getEdge() {
495         return edge;
496     }
497     double getPerimeter() {
498         double c = 0;
499         for (double length : edgeLength)
500             c += length;
501         return c;
502     }
503     abstract double getArea();
504     /*判断是否为凸多边形:输入:无;输出:是:true;否:false */
505     boolean isConvexPolygon() {
506         boolean index = true;
507         ArrayList<Point> vertexArrayList = new ArrayList<>(Arrays.asList(vertex));
508         /* 若任意一顶点在剩余顶点所构成多边形内部则为凹多边形,否则为凸多边形 */
509         for (int i = 0; i < vertexArrayList.size(); i++) {
510             Point tpoint = vertexArrayList.get(i);
511             vertexArrayList.remove(i);
512             Point[] tVertex = new Point[vertexArrayList.size()];
513             vertexArrayList.toArray(tVertex);
514             Polygon t = null;
515             switch (vertexArrayList.size()) {
516             case 3:
517                 t = new Triangle(tVertex);                
518                 break;
519             case 4:
520                 t = new Quadrilateral(tVertex);
521                 break;
522             }
523             if (t.isPointInPolygon(tpoint)) {
524                 index = false;
525             }
526             vertexArrayList.add(i, tpoint);
527         }
528         return index;
529     }
530     /* 判断点是否在多边形内:输入:无;输出:是:true;否:false */
531     boolean isPointInPolygon(Point pt) {
532         Point[] pts = this.getVertex();
533         int counter = 0;
534         double xinters;
535         Point p1,p2;
536         for(int i = 0;i < pts.length;i++) {
537             p1 = pts[i]; 
538             p2 = pts[(i + 1) % pts.length];
539             if (Math.min(p1.getY(),p2.getY()) < pt.getY() && pt.getY() <= Math.max(p1.getY(),p2.getY())) {
540                 xinters = (pt.getY() - p1.getY()) * (p2.getX() - p1.getX()) / (p2.getY() - p1.getY()) + p1.getX();
541                 if (p1.getY() == p2.getY() || pt.getX() <= xinters) {
542                     counter++;
543                 }
544             }
545         }
546         return (counter % 2 != 0);
547     }
548     /* 判断点是否在多边形上:输入:无;输出:是:true;否:false */
549     boolean isPointOnPolygon(Point p) {
550         boolean index = false;
551         for(int i = 0;i < numberOfEdge;i++)
552             if(edge[i].isPointOnLine(p) && edge[i].isOnSegment(p))
553                 index = true;
554         return index;
555     }
556 
557     /* 区分输入的点构成三角形还是四边形:若能构成则返回三角形或四边形对象;若不能则抛出错误 */
558     static Polygon distinguish(Point[] p) throws IllegalArgumentException{
559         
560         Polygon polygon = null;
561         try {
562             polygon = new Quadrilateral(p);
563             //若不能构成四边形则抛出错误,判断是否能构成三角形
564         } 
565         catch (IllegalArgumentException ex1) {
566             try {
567                 p = Triangle.isTriangle(p);
568                 polygon = new Triangle(p);
569             } 
570             catch (IllegalArgumentException ex2) {
571                 throw new IllegalArgumentException("not a quadrilateral or triangle");
572             }
573         }
574         return polygon;
575     }
576     /* 判断直线是否与多边形某条边重合:是则抛出错误 */
577     void isLineCoincideWithEdge(Line l) throws IllegalArgumentException{
578         boolean index = false;
579         for (int i = 0; i < edge.length; i++) {
580             if (edge[i].isLineCoincideWithLine(l))
581                 index = true;
582         }
583         if(index)
584             throw new IllegalArgumentException("The line is coincide with one of the lines");
585     }
586     /* 求直线与多边形交点 */
587     Point[] intersectionOfLineAndPolygon(Line l) {
588         Point[] intersection = null;
589         ArrayList<Point> potential = new ArrayList<>();
590         /*求出直线与每一条边的交点*/
591         for(int i = 0;i < numberOfEdge;i++) {
592             Point a = l.intersectionOfTwoLines(edge[i]);
593             if(a != null && edge[i].isOnSegment(a))
594                 potential.add(l.intersectionOfTwoLines(edge[i]));
595         }
596         /* 排除重复的点,即直线与多边形顶点的交点 */
597         for(int i = 0;i < potential.size();i++) 
598             for(int j = i + 1;j < potential.size();j++) 
599                 if(potential.get(i).isCoincide(potential.get(j)))
600                     potential.remove(j);
601         
602         intersection = new Point[potential.size()];
603         potential.toArray(intersection);
604         return intersection;
605     }
606     Point[] whichSideOfLine(Line l) {
607         Point[] p = null;
608         ArrayList<Point> p1 = new ArrayList<>();
609         ArrayList<Point> p2 = new ArrayList<>();
610         for(int i = 0;i < numberOfEdge;i++) {
611             if(l.whichSideOfLine(vertex[i]) == 1)
612                 p1.add(vertex[i]);
613             else if(l.whichSideOfLine(vertex[i]) == 2)
614                 p2.add(vertex[i]);
615         }
616         if (p1.size() <= p2.size()) {
617             p =  new Point[p1.size()];
618             p1.toArray(p);
619         } 
620         else {
621             p =  new Point[p2.size()];
622             p2.toArray(p);
623         }
624         return p;
625     }
626 }
复制代码

 

    • 第五次作业
      •  用户输入一组选项和数据,进行与五边形有关的计算。
        以下五边形顶点的坐标要求按顺序依次输入,连续输入的两个顶点是相邻顶点,第一个和最后一个输入的顶点相邻。
        选项包括:
        1
        :输入五个点坐标,判断是否是五边形,判断结果输出true/false
        2
        :输入五个点坐标,判断是凹五边形(false)还是凸五边形(true),如果是凸五边形,则再输出五边形周长、面积,结果之间以一个英文空格符分隔。若五个点坐标无法构成五边形,输出"not a pentagon"
        3
        :输入七个点坐标,前两个点构成一条直线,后五个点构成一个凸五边形、凸四边形或凸三角形,输出直线与五边形、四边形或三角形相交的交点数量。如果交点有两个,再按面积从小到大输出被直线分割成两部分的面积(不换行)。若直线与多边形形的一条边线重合,输出"The line is coincide with one of the lines"。若后五个点不符合五边形输入,若前两点重合,输出"points coincide"

        以上3选项中,若输入的点无法构成多边形,则输出"not a polygon"。输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是xy,边线中间有一点z,另一顶点s
        1
        )符合要求的输入:顶点重复或者zxy都相邻,如:x x y sx z y sx y x ss x y y。此时去除冗余点,保留一个x、一个y
        2)
        不符合要求的输入:z不与xy都相邻,如:z x y sx z s yx s z y

        4:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),判断它们两个之间是否存在包含关系(一个多边形有一条或多条边与另一个多边形重合,其他部分都包含在另一个多边形内部,也算包含)。
        两者存在六种关系:1、分离(完全无重合点) 2、连接(只有一个点或一条边重合) 3、完全重合 4、被包含(前一个多边形在后一个多边形的内部)5、交错 6、包含(后一个多边形在前一个多边形的内部)。
        各种关系的输出格式如下:
        1
        no overlapping area between the previous triangle/quadrilateral/ pentagon and the following triangle/quadrilateral/ pentagon
        2
        the previous triangle/quadrilateral/ pentagon is connected to the following triangle/quadrilateral/ pentagon
        3
        the previous triangle/quadrilateral/ pentagon coincides with the following triangle/quadrilateral/ pentagon
        4
        the previous triangle/quadrilateral/ pentagon is inside the following triangle/quadrilateral/ pentagon
        5
        the previous triangle/quadrilateral/ pentagon is interlaced with the following triangle/quadrilateral/ pentagon
        6
        the previous triangle/quadrilateral/ pentagon contains the following triangle/quadrilateral/ pentagon

        5:输入十个点坐标,前、后五个点分别构成一个凸多边形(三角形、四边形、五边形),输出两个多边形公共区域的面积。注:只考虑每个多边形被另一个多边形分割成最多两个部分的情况,不考虑一个多边形将另一个分割成超过两个区域的情况。

        6:输入六个点坐标,输出第一个是否在后五个点所构成的多边形(限定为凸多边形,不考虑凹多边形),的内部(若是五边形输出in the pentagon/outof the pentagon,若是四边形输出in the quadrilateral/outof the quadrilateral,若是三角形输出in the triangle/outof the triangle)。输入入错存在冗余点要排除,冗余点的判定方法见选项5。如果点在多边形的某条边上,输出"on the triangle/on the quadrilateral/on the pentagon"
        以上456选项输入的五个点坐标可能存在冗余,假设多边形一条边上两个端点分别是xy,边线中间有一点z,另一顶点s
        1
        )符合要求的输入:顶点重复或者zxy都相邻,如:x x y sx z y sx y x ss x y y。此时去除冗余点,保留一个x、一个y
        2)
        不符合要求的输入:z不与xy都相邻,如:z x y sx z s yx s z y

 

 

 三角形、四边形、五边形类均继承自多边形类,处理选项4和5的多边形类方法getRelationship()和getPublicArea()方法参数均为抽象类Polygon,利用多态特性简化代码

 

 3、4、5、6选项均为三角形、四边形、五边形都可能出现,所以创建对象时均采用多边形类创建,以便利用多态特征简化代码。

         以选项六为例,在distinguish方法中创建多边形对象,然后使用instanceof关键字判断是哪一类对象从而确定输出,而求点是否在多边形内部的方法定义在抽象父类Polygon中,简化各种判断,代码如下:

        

复制代码
 1 private static void condition6(Point[] p) {
 2         Point[] vertex = new Point[5];
 3         System.arraycopy(p, 1, vertex, 0, vertex.length);
 4         Polygon polygon = Polygon.distinguish(vertex);
 5         String string1 = null;
 6         if (polygon instanceof Triangle)
 7             string1 = "triangle";
 8         else if(polygon instanceof Quadrilateral)
 9             string1 = "quadrilateral";
10         else 
11             string1 = "pentagon";
12         String string2 = null;
13         if(polygon.isPointOnPolygon(p[0]))
14             string2 = "on the ";
15         else if(polygon.isPointInPolygon(p[0]))
16             string2 = "in the ";
17         else
18             string2 = "outof the ";
19 
20         System.out.println(string2 + string1);
21     }
复制代码

 

 

         

 

    • 期中考试

      • 1.设计一个类表示平面直角坐标系上的点Point,私有属性分别为横坐标x与纵坐标y,数据类型均为实型数,除构造方法以及属性的getter与setter方法外,定义一个用于显示信息的方法display(),用来输出该坐标点的坐标信息,格式如下:(x,y),数值保留两位小数。为简化题目,其中,坐标点的取值范围设定为(0,200]。若输入有误,系统则直接输出Wrong Format。设计一个类表示平面直角坐标系上的线Line,私有属性除了标识线段两端的点point1、point2外,还有一个字符串类型的color,用于表示该线段的颜色,同样,除构造方法以及属性的getter与setter方法外,定义一个用于计算该线段长度的方法getDistance(),还有一个用于显示信息的方法display(),用来输出线段的相关信息,输出格式如下:

题目较为简单,按要求写出即可,代码如下:

复制代码
  1 package mid;
  2 
  3 import java.util.Scanner;
  4 import static java.lang.Math.*;
  5 
  6 public class Main {
  7     public static void main(String[] args) {
  8         Scanner input = new Scanner(System.in);
  9         double beginX = input.nextDouble();
 10         double beginY = input.nextDouble();
 11         double endX = input.nextDouble();
 12         double endY = input.nextDouble();
 13         String color = input.next();
 14         try {
 15             Point begin = new Point(beginX,beginY);
 16             Point end = new Point(endX,endY);
 17             Line line = new Line(begin,end,color);
 18             line.display();            
 19         } 
 20         catch (IllegalArgumentException ex) {
 21             System.out.println(ex.getMessage());
 22         }
 23         input.close();
 24     }
 25 }
 26 
 27 class Point {
 28     private double x;
 29     private double y;
 30     
 31     public Point() {
 32         this(0, 0);
 33     }
 34     
 35     public Point(double x,double y) {
 36         if(x <=0 || x > 200 || y <=0 || y > 200)
 37             throw new IllegalArgumentException("Wrong Format");
 38         this.x = x;
 39         this.y = y;
 40     }
 41     
 42     public double getX() {
 43         return x;
 44     }
 45     
 46     public double getY() {
 47         return y;
 48     }
 49     
 50     public void setX(double x) {
 51         this.x = x;
 52     }
 53     
 54     public void setY(double y) {
 55         this.y = y;
 56     }
 57     
 58     void display() {
 59         System.out.println("(" + String.format("%.2f", x) +"," + String.format("%.2f", y) + ")");
 60     }
 61 }
 62 
 63 class Line {
 64     private Point point1;
 65     private Point point2;
 66     private String color;
 67     
 68     public Line() {
 69     }
 70     
 71     public Line(Point point1,Point point2,String color) {
 72         this.point1 = point1;
 73         this.point2 = point2;
 74         this.color = color;
 75     }
 76     
 77     public void setPoint1(Point point1) {
 78         this.point1 = point1;
 79     }
 80     
 81     public void setPoint2(Point point2) {
 82         this.point2 = point2;
 83     }
 84     
 85     public void setColor(String color) {
 86         this.color = color;
 87     }
 88     
 89     public Point getPoint1() {
 90         return point1;
 91     }
 92     
 93     public Point getPoint2() {
 94         return point2;
 95     }
 96     
 97     public String getColor() {
 98         return color;
 99     }
100     
101     double getDistance() {
102         double distance = sqrt(pow(point1.getX() - point2.getX(), 2) + pow(point1.getY() - point2.getY(), 2));
103         return distance;
104     }
105     
106     void display() {
107         System.out.println("The line's color is:" + color);
108         System.out.println("The line's begin point's Coordinate is:");
109         point1.display();
110         System.out.println("The line's end point's Coordinate is:");
111         point2.display();
112         System.out.println("The line's length is:" + String.format("%.2f", getDistance()));
113     }
114 }
复制代码

 

 

      • 2.对题目中的点Point类和线Line类进行进一步抽象,定义一个两个类的共同父类Element(抽象类),将display()方法在该方法中进行声明(抽象方法),将Point类和Line类作为该类的子类。再定义一个Element类的子类面Plane,该类只有一个私有属性颜色color,除了构造方法和属性的getter、setter方法外,display()方法用于输出面的颜色,输出格式如下:The Plane's color is:颜色在主方法内,定义两个Point(线段的起点和终点)对象、一个Line对象和一个Plane对象,依次从键盘输入两个Point对象的起点、终点坐标和颜色值(Line对象和Plane对象颜色相同),然后定义一个Element类的引用,分别使用该引用调用以上四个对象的display()方法,从而实现多态特性。

代码如下:

复制代码
  1 package mid2;
  2 
  3 import java.util.Scanner;
  4 import static java.lang.Math.*;
  5 
  6 public class Main {
  7     public static void main(String[] args) {
  8         Scanner input = new Scanner(System.in);
  9         double beginX = input.nextDouble();
 10         double beginY = input.nextDouble();
 11         double endX = input.nextDouble();
 12         double endY = input.nextDouble();
 13         String color = input.next();
 14         try {
 15             Point p1 = new Point(beginX,beginY);
 16             Point p2 = new Point(endX,endY);
 17             Line line = new Line(p1,p2,color);
 18             Plane plane = new Plane(color);
 19             
 20             Element element = null;
 21             element = p1;//起点Point
 22             element.display();
 23               
 24             element = p2;//终点Point
 25             element.display();
 26               
 27             element = line;//线段
 28             element.display();
 29               
 30             element = plane;//
 31             element.display();
 32 
 33         } 
 34         catch (IllegalArgumentException ex) {
 35             System.out.println(ex.getMessage());
 36         }
 37         input.close();
 38     }
 39 }
 40 
 41 abstract class Element {
 42     abstract void display();
 43 }
 44 
 45 class Point extends Element{
 46     private double x;
 47     private double y;
 48     
 49     public Point() {
 50         this(0, 0);
 51     }
 52     
 53     public Point(double x,double y) {
 54         if(x <=0 || x > 200 || y <=0 || y > 200)
 55             throw new IllegalArgumentException("Wrong Format");
 56         this.x = x;
 57         this.y = y;
 58     }
 59     
 60     public double getX() {
 61         return x;
 62     }
 63     
 64     public double getY() {
 65         return y;
 66     }
 67     
 68     public void setX(double x) {
 69         this.x = x;
 70     }
 71     
 72     public void setY(double y) {
 73         this.y = y;
 74     }
 75     
 76     @Override
 77     void display() {
 78         System.out.println("(" + String.format("%.2f", x) +"," + String.format("%.2f", y) + ")");
 79     }
 80 }
 81 
 82 class Line extends Element{
 83     private Point point1;
 84     private Point point2;
 85     private String color;
 86     
 87     public Line() {
 88     }
 89     
 90     public Line(Point point1,Point point2,String color) {
 91         this.point1 = point1;
 92         this.point2 = point2;
 93         this.color = color;
 94     }
 95     
 96     public void setPoint1(Point point1) {
 97         this.point1 = point1;
 98     }
 99     
100     public void setPoint2(Point point2) {
101         this.point2 = point2;
102     }
103     
104     public void setColor(String color) {
105         this.color = color;
106     }
107     
108     public Point getPoint1() {
109         return point1;
110     }
111     
112     public Point getPoint2() {
113         return point2;
114     }
115     
116     public String getColor() {
117         return color;
118     }
119     
120     double getDistance() {
121         double distance = sqrt(pow(point1.getX() - point2.getX(), 2) + pow(point1.getY() - point2.getY(), 2));
122         return distance;
123     }
124     
125     @Override
126     void display() {
127         System.out.println("The line's color is:" + color);
128         System.out.println("The line's begin point's Coordinate is:");
129         point1.display();
130         System.out.println("The line's end point's Coordinate is:");
131         point2.display();
132         System.out.println("The line's length is:" + String.format("%.2f", getDistance()));
133     }
134 }
135 
136 class Plane extends Element {
137     private String color;
138     
139     public Plane(String color) {
140         this.color = color;
141     }
142     public Plane() {
143     }
144     
145     public void setColor(String color) {
146         this.color = color;
147     }
148     
149     public String getColor() {
150         return color;
151     }
152     
153     @Override
154     void display() {
155         System.out.println("The Plane's color is:" + color);
156         
157     }
158     
159 }
复制代码

 

      • 3.在“点与线(继承与多态)”题目基础上,对题目的类设计进行重构,增加容器类保存点、线、面对象,并对该容器进行相应增、删、遍历操作。在原有类设计的基础上,增加一个GeometryObject容器类,其属性为ArrayList<Element>类型的对象(若不了解泛型,可以不使用<Element>)增加该类的add()方法及remove(int index)方法,其功能分别为向容器中增加对象及删除第index - 1(ArrayList中index>=0)个对象在主方法中,用户循环输入要进行的操作(choice∈[0,4]),其含义如下:1:向容器中增加Point对象;2:向容器中增加Line对象;3:向容器中增加Plane对象;4:删除容器中第index - 1个数据,若index数据非法,则无视此操作;0:输入结束

 在index非法的情况下,ArrayList的remove方法本身就会抛出错误,要无视错误操作则直接catch后不做任何操作即可,代码如下:

1 case 4://delete index - 1 object from list
2                     int index = input.nextInt();
3                     try {
4                         geometryObject.remove(index);                        
5                     } 
6                     catch (Exception e) {
7                     }
8                 }

 

完整代码如下:

复制代码
  1 package mid3;
  2 
  3 import java.util.ArrayList;
  4 import java.util.Scanner;
  5 import static java.lang.Math.*;
  6 
  7 public class Main {
  8     public static void main(String[] args) {
  9         Scanner input = new Scanner(System.in);
 10         try {
 11             GeometryObject geometryObject = new GeometryObject();
 12             int choice = input.nextInt();
 13             while(choice != 0) {
 14                 switch(choice) {
 15                 case 1://insert Point object into list 
 16                     double pX = input.nextDouble();
 17                     double pY = input.nextDouble();
 18                     geometryObject.add(new Point(pX,pY));
 19                     break;
 20                 case 2://insert Line object into list
 21                     double beginX = input.nextDouble();
 22                        double beginY = input.nextDouble();
 23                     double endX = input.nextDouble();
 24                        double endY = input.nextDouble();
 25                        String color1 = input.next();
 26                        geometryObject.add(new Line(new Point(beginX,beginY),new Point(endX,endY),color1));
 27                        break;
 28                 case 3://insert Plane object into list
 29                     String color2 = input.next();
 30                     geometryObject.add(new Plane(color2));
 31                     break;
 32                 case 4://delete index - 1 object from list
 33                     int index = input.nextInt();
 34                     try {
 35                         geometryObject.remove(index);                        
 36                     } 
 37                     catch (Exception e) {
 38                     }
 39                 }
 40                 choice = input.nextInt();
 41             }
 42             for (Element element : geometryObject.getList()) {
 43                 element.display();
 44             }
 45 
 46         } 
 47         catch (IllegalArgumentException ex) {
 48             System.out.println(ex.getMessage());
 49         }
 50         input.close();
 51     }
 52 }
 53 
 54 abstract class Element {
 55     abstract void display();
 56 }
 57 
 58 class Point extends Element{
 59     private double x;
 60     private double y;
 61     
 62     public Point() {
 63         this(0, 0);
 64     }
 65     
 66     public Point(double x,double y) {
 67         if(x <=0 || x > 200 || y <=0 || y > 200)
 68             throw new IllegalArgumentException("Wrong Format");
 69         this.x = x;
 70         this.y = y;
 71     }
 72     
 73     public double getX() {
 74         return x;
 75     }
 76     
 77     public double getY() {
 78         return y;
 79     }
 80     
 81     public void setX(double x) {
 82         this.x = x;
 83     }
 84     
 85     public void setY(double y) {
 86         this.y = y;
 87     }
 88     
 89     @Override
 90     void display() {
 91         System.out.println("(" + String.format("%.2f", x) +"," + String.format("%.2f", y) + ")");
 92     }
 93 }
 94 
 95 class Line extends Element{
 96     private Point point1;
 97     private Point point2;
 98     private String color;
 99     
100     public Line() {
101     }
102     
103     public Line(Point point1,Point point2,String color) {
104         this.point1 = point1;
105         this.point2 = point2;
106         this.color = color;
107     }
108     
109     public void setPoint1(Point point1) {
110         this.point1 = point1;
111     }
112     
113     public void setPoint2(Point point2) {
114         this.point2 = point2;
115     }
116     
117     public void setColor(String color) {
118         this.color = color;
119     }
120     
121     public Point getPoint1() {
122         return point1;
123     }
124     
125     public Point getPoint2() {
126         return point2;
127     }
128     
129     public String getColor() {
130         return color;
131     }
132     
133     double getDistance() {
134         double distance = sqrt(pow(point1.getX() - point2.getX(), 2) + pow(point1.getY() - point2.getY(), 2));
135         return distance;
136     }
137     
138     @Override
139     void display() {
140         System.out.println("The line's color is:" + color);
141         System.out.println("The line's begin point's Coordinate is:");
142         point1.display();
143         System.out.println("The line's end point's Coordinate is:");
144         point2.display();
145         System.out.println("The line's length is:" + String.format("%.2f", getDistance()));
146     }
147 }
148 
149 class Plane extends Element {
150     private String color;
151     
152     public Plane(String color) {
153         this.color = color;
154     }
155     public Plane() {
156     }
157     
158     public void setColor(String color) {
159         this.color = color;
160     }
161     
162     public String getColor() {
163         return color;
164     }
165     
166     @Override
167     void display() {
168         System.out.println("The Plane's color is:" + color);
169         
170     }
171     
172 }
173 
174 class GeometryObject{
175     private ArrayList<Element> list = new ArrayList<>();
176     
177     public GeometryObject() {
178     }
179     void add(Element element) {
180         list.add(element);
181     }
182     
183     void remove(int index) {
184         list.remove(index - 1);
185     }
186     
187     public ArrayList<Element> getList() {
188         return list;
189     }
190 }
复制代码

 

 

 

 

  • 踩坑心得:

    1. 如果抛出(throw)了异常一定要进行捕获(catch),否则程序会直接退出。如果希望程序只是忽略这个异常则可以在catch块中什么都不做。
    2. 可以使用语句import static java.lang.Math.*;来使使用数学函数时省略Math,增加代码可读性。
  • 改进建议:

    1. 类class的访问器getter不应该返回类内部属性对象的引用,这样会使得外部仍然有可能更改类的private属性,这样就使封装失去了意义,解决方法为使用Object类中的clone方法(在属性对象中还有别的时需要重写)

    2. 类的属性不应该能从别的属性中推导而来,如果有则很可能在修改其中一个时没有更新另一个产生冲突
    3. 谨慎使用继承关系,父类和子类应该是一种严格的“是-一种”(is-a)关系,不要简单地为了复用一个方法而继承自一个父类
    4. 为了使类拥有某个方法时可以使用接口(interface)
  • 总结:

    • 经过这个月的学习对面向对戏程序设计的三大支柱有了初步的认识与应用,是一次令人印象深刻的练习与难能可贵的进步,让我初步窥探到了面向对象程序设计的精妙与便捷之处。

posted on   Zexu1016  阅读(30)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示