public abstract class GeometricObject { private String color = "blue"; public String getColor() { return color; } public void printArea() { System.out.printf("The area of %s is %f\n", this, this.area()); } public void setColor(String color) { this.color = color; } public abstract double area(); // must be overridden } public class Point extends GeometricObject { protected double x, y; public Point(double x, double y) { this.x = x; this.y = y; } public double distTo (Point p) { return Math.sqrt(Math.pow(this.x-p.x,2)+Math.pow(this.y-p.y,2)); } public double area() { return 0; } } public class Quadrilateral extends GeometricObject { protected Point p1, p2, p3, p4; public Quadrilateral (Point p1, Point p2, Point p3, Point p4) { // should check these points for a convex quadrillateral in this order this.p1 = p1; this.p2 = p2; this.p3 = p3; this.p4 = p4; } public double area() { // diagonal gives 2 triangles; use semiperimeter formula double diag = p1.distTo(p3); double s12 = p1.distTo(p2); double s23 = p2.distTo(p3); double s34 = p3.distTo(p4); double s41 = p4.distTo(p1); double semi1 = (s12 + s23 + diag) / 2; double semi2 = (diag + s34 + s41) / 2; return Math.sqrt(semi1 * (semi1-s12) * (semi1-s23) * (semi1-diag)) + Math.sqrt(semi2 * (semi2-s34) * (semi2-s41) * (semi2-diag)); } } public class Rectangle extends Quadrilateral { private double width, height; public Rectangle(Point p1, Point p2, Point p3, Point p4) { super(p1, p2, p3, p4); width = p1.distTo(p2); height = p2.distTo(p3); // should check that all angles are right angles via slopes neg recip } public Rectangle(Point p1, Point p3) { // Sides parallel to the axes super(p1, new Point(p3.x,p1.y), p3, new Point(p1.x,p3.y)); width = Math.abs(p1.x-p3.x); height = Math.abs(p1.y-p3.y); // Nothing to check } public double getWidth() { return width; } public double getHeight() { return height; } public double area() { return width * height; } } public class Rhombus extends Quadrilateral { private double sideLength; public Rhombus (Point p1, Point p2, Point p3, Point p4) throws Exception { super(p1, p2, p3, p4); double s12 = p1.distTo(p2); if (s12!=p2.distTo(p3) || s12!=p3.distTo(p4) || s12!=p4.distTo(p1)) throw new Exception ("Rhombus with unequal sides."); sideLength = s12; } // Rhombus parallel to X axis; given sideLength; interior angle theta public Rhombus (Point p, double sideLength, double theta) { super (p, new Point(p.x+sideLength*Math.cos(theta), p.y+sideLength*Math.sin(theta)), new Point(p.x+sideLength*(Math.cos(theta)+1.), p.y+sideLength*Math.sin(theta)), new Point(p.x+sideLength, p.y)); this.sideLength = sideLength; } public double getSideLength() { return sideLength; } } public class TestQuad { public static void main (String[] args) throws Exception { Point origin = new Point(0.0,0.0); Point p1 = new Point(1.0,0.0); Point p2 = new Point(1.0,1.0); Point p3 = new Point(0.0,1.0); Point p4 = new Point(5.0,5.0); Quadrilateral quad1 = new Quadrilateral(origin, p3, new Point(5.,0.), new Point(5.,-8.)); Rectangle rect1 = new Rectangle (origin,p1,p2,p3); Rectangle rect2 = new Rectangle (origin, new Point(1.0,4.0)); Rhombus rhom1; try { rhom1 = new Rhombus(origin,origin,p2,p3); } catch (Exception ex) { System.out.printf("rhom1 error: %s Using unit square.\n", ex.getMessage()); rhom1 = new Rhombus (origin, 1.0, Math.PI/2.0); } p1.printArea(); printColor(rhom1); // Polymorphic call (section 11.7) printColor(rect1); // Polymorphic call quad1.printArea(); // Inherited method (section first try) rect2.printArea(); // Inherited method myPrintArea(rhom1); // Dynamic binding/dispatch (section second try) myPrintArea(p4); // Dynamic binding/dispatch quad1 = rect1; // implicit casting (section 11.9) quad1.printArea(); // dynamic binding/dispatch Circle c1 = new Circle(); Circle c2 = new Circle(2.); Circle c3 = new Circle(); System.out.println(c3.equals(c1)); Circle c = Circle.largestCircle(); c.printArea(); System.out.println(c.getColor()); GeometricObject geo1 = new Rectangle(origin, p2); GeometricObject geo2 = new Rhombus(origin, new Point(3,4), new Point(8,4), new Point(5,0)); System.out.println(geo1.area()); } public static void printColor(GeometricObject geoObj) { System.out.printf("The color of %s is %s\n", geoObj, geoObj.getColor()); } public static void myPrintArea(GeometricObject geoObj) { System.out.printf("My area of %s is %f\n", geoObj, geoObj.area()); } }